0

我正在尝试创建一个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

4 回答 4

1

看到你不应该担心底层实现,这就是java中“封装”的意图。根据 Oracle 文档,“放置”实际上是在尾部“插入”元素。所以我想没有任何替代“旧对象”。

于 2012-02-09T14:58:56.720 回答
1

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

E[] items;

并在您的情况下实例化为

Integer[] items;

根据源码ArrayBlockingQueueput方法实际上调用了这个insert方法:

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

所以当你调用时发生pool.put(6)的事情是int6 被装箱到一个Integer对象中并传递给方法(因为E是 now Integer)。所以可以肯定地说,它确实创建了一个新的Integer.

于 2012-02-09T15:49:57.517 回答
0

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

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

于 2012-02-09T15:13:22.977 回答
0

新对象是在这里创建的:

pool.put(6);

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

pool.put(new Integer(6));

队列既不创建也不重用这些对象,它存储你给它的那些。

于 2012-02-09T15:16:11.597 回答