此对象池是否会导致多个线程出现可见性问题?我特别想知道这种执行顺序:
在 B修改了状态本身后,线程B 可能会对线程A的修改可见吗? (我知道它在实践中不会发生,但我无法弄清楚JLS / Javadoc是否以及如何保证这一点。)
这是代码,仅限于显示要点。我遗漏了一般化和工厂来创造物品。
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
public class ObjectPool {
/** Maximum number of objects to be kept in pool */
int maxPoolSize = 10;
/** First object in pool (LIFO queue) */
final AtomicReference<PoolableObject> firstObject = new AtomicReference<PoolableObject>();
/** How many objects are currently in the pool */
final AtomicInteger poolSize = new AtomicInteger();
/** Gets an object from the pool. If no object is available
* from the pool, a new object is created and returned */
public PoolableObject obtainObject() {
while (true) {
PoolableObject object = firstObject.get();
if (object == null)
break;
if (firstObject.compareAndSet(object, object.next)) {
poolSize.decrementAndGet();
return object;
}
}
// no more objects in pool, create a new object
return new PoolableObject();
}
/** Returns an object to the pool. */
public void releaseObject(final PoolableObject object) {
while (true) {
if (poolSize.get() >= maxPoolSize)
break;
final PoolableObject first = firstObject.get();
object.next = first;
if (firstObject.compareAndSet(first, object)) {
poolSize.incrementAndGet();
break;
}
}
}
}
池管理的对象应该从这个类继承:
public class PoolableObject {
/** Links objects in pool in single linked list. */
PoolableObject next;
public int visibleState;
}
答案 0 :(得分:0)
就知名度而言,AtomicReference
has the same memory barrier properties as a volatile
variable.
在这些属性中,线程的所有操作都是在写入易失性变量“发生之前”之后写入的。或者,换句话说,如果源代码显示在易失性写入之前发生的操作,则JITC无法在易失性写入之后重新排序该操作。因此,问题中引用的情景不会成为问题;在释放之前对象所做的更改将随后捕获该对象的其他线程可见。
但是,我并没有完全按照这个池的工作方式,可能还有其他问题。特别是,我不相信firstObject
和poolSize
之间缺乏原子性是安全的。线程肯定可以看到这些变量处于不一致状态,因为它们不是synchronized
;我不知道这是否重要。