简体   繁体   English

ArrayBlockingQueue:应该用来创建Pool吗?

[英]ArrayBlockingQueue: should use to create Pool?

I'm trying to create a Pool object to reserve old objects in case of use them again (to avoid instantiation of new objects). 我正在尝试创建一个Pool对象来保留旧对象,以便再次使用它们(以避免实例化新对象)。 I google that ArrayBlockingQueue and some people use it to create Pool . 我谷歌说ArrayBlockingQueue和一些人用它来创建Pool But there is one question I don't know: does it recreate a new instance when an object insert to it. 但是有一个我不知道的问题:它是否在对象插入时重新创建一个新实例。

For example: ArrayBlockingQueue<Integer> pool = new ArrayBlockingQueue<Integer>(3); 例如: ArrayBlockingQueue<Integer> pool = new ArrayBlockingQueue<Integer>(3);

after short time: pool = (3,4,5); 在短时间后: pool = (3,4,5);

pool.take(5); ==> pool = (3,4);
pool.put(6);  ==>pool = (6,3,4);

So, I wonder is 6 assigned to the old Integer object (with value 5), or does Java create a new one and assign it's value as 6? 所以,我想知道6是分配给旧的Integer对象(值为5),还是Java创建了一个新的并将其值赋值为6?

thanks :) 谢谢 :)

See you shouldn't worry about the underlying implementation, that is what is intended in java by "encapsulation". 看你不应该担心底层实现,这就是“封装”在java中的意图。 According to the Oracle docs, "put" actually "inserts" the element at the tail. 根据Oracle文档,“put”实际上“插入”了尾部的元素。 So there isn't any replacement of "old objects", i suppose. 因此,我认为没有任何“旧物体”的替代品。

The ArrayBlockingQueue is backed by an array of the parameter type. ArrayBlockingQueue由参数类型的数组支持。 So internally it would look something like this: 所以内部看起来像这样:

E[] items;

and instantiated in your case as 并在你的情况下实例化为

Integer[] items;

According to the source code of ArrayBlockingQueue , the put method actually calls this insert method: 根据ArrayBlockingQueue源代码put方法实际上调用了这个insert方法:

private void insert(E x) {
    items[putIndex] = x;
    putIndex = inc(putIndex);
    ++count;
    notEmpty.signal();
}

So what happens when you call pool.put(6) is that the int 6 is boxed into an Integer object and passed to the method (since E is now Integer ). 那么当你调用pool.put(6)时会发生的事情是int 6被装入一个Integer对象并传递给方法(因为E现在是Integer )。 So it's safe to say that indeed it does create a new instance of Integer . 所以可以肯定地说它确实创建了一个新的Integer实例。

I would seriously doubt that any replacing of values would be actual in this case. 我会严重怀疑在这种情况下,任何替换值都是实际的。 Furthermore, I am not sure having a custom implementation of such an object pool would be useful, unless your code generates and trashes an immense number of objects. 此外,我不确定这样的对象池的自定义实现是否有用,除非您的代码生成并删除了大量的对象。

What's more interesting is that you do not mention anything about thread safety or multithreading in your question, but you have used these tags. 更有趣的是,你没有在你的问题中提到线程安全或多线程的任何内容,但你已经使用过这些标签。 What exactly is it that you want to achieve with such a pool? 你想用这样的游泳池实现什么? ArrayBlockingQueue is intended as a thread-safe collection where one (or many) threads dump in objects while one (or many) threads remove objects out. ArrayBlockingQueue旨在作为线程安全的集合,其中一个(或多个)线程在对象中转储,而一个(或多个)线程将对象移出。 There are quite a few methods to supply different behaviors in case an objects is required from the queue but there is none, or when an objects is added but there is no capacity in the queue. 如果队列中需要对象但没有对象,或者添加了对象但队列中没有容量,则有很多方法可以提供不同的行为。 You should check out the javadoc and see if it's really ArrayBlockingQueue you want. 您应该查看javadoc并查看它是否真的是您想要的ArrayBlockingQueue

The new object was created right here: 新对象就在这里创建:

pool.put(6);

It's more obvious when you think what autoboxing is converting that to: 当您认为自动装箱将其转换为以下内容时,这一点更为明显:

pool.put(new Integer(6));

The queue neither creates nor reuses these objects, it stores the ones you give it. 队列既不创建也不重用这些对象,它存储您提供的对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM