我试图创建一个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?
谢谢:)
答案 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));
队列既不创建也不重用这些对象,它会存储您提供的对象。