ArrayBlockingQueue:应该用来创建Pool吗?

时间:2012-02-09 14:54:55

标签: java multithreading java.util.concurrent

我试图创建一个Pool对象来保留旧对象,以防再次使用它们(以避免实例化新对象)。我谷歌ArrayBlockingQueue,有些人用它来创建Pool。但是有一个问题我不知道:它是否在对象插入时重新创建一个新实例。

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

短时间后:pool = (3,4,5);

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

所以,我想知道是6分配给旧的Integer对象(值为5),还是Java创建了一个新的并将其值分配为6?

谢谢:)

4 个答案:

答案 0 :(得分:1)

看到你不应该担心底层实现,这是“封装”在Java中的意图。根据Oracle文档,“put”实际上“插入”了尾部的元素。因此,我认为没有任何“旧物品”的替代品。

答案 1 :(得分:1)

ArrayBlockingQueue由参数类型的数组支持。所以内部看起来像这样:

E[] items;

并在您的情况下实例化为

Integer[] items;

根据ArrayBlockingQueue的{​​{3}},put方法实际上会调用此insert方法:

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

因此,当您致电pool.put(6)时会发生什么,int 6被装入Integer对象并传递给方法(因为E现在是{{1} }})。所以可以肯定地说它确实创建了Integer的新实例。

答案 2 :(得分:0)

我会严重怀疑在这种情况下,任何替换值都是实际的。此外,我不确定这样的对象池的自定义实现是否有用,除非您的代码生成并删除了大量的对象。

更有趣的是,您在问题中没有提及线程安全或多线程的任何内容,但您已经使用过这些标记。你想用这样的游泳池实现什么? ArrayBlockingQueue旨在作为线程安全的集合,其中一个(或多个)线程在对象中转储,而一个(或多个)线程将对象移出。如果队列中需要对象但没有对象,或者添加了对象但队列中没有容量,则有很多方法可以提供不同的行为。您应该查看javadoc,看看它是否真的ArrayBlockingQueue

答案 3 :(得分:0)

新对象就在这里创建:

pool.put(6);

当您认为自动装箱将其转换为:

时,更为明显
pool.put(new Integer(6));

队列既不创建也不重用这些对象,它会存储您提供的对象。