이 개체 풀이 여러 스레드에서 가시성 문제를 일으킬 수 있습니까? 내가 특별히 실행 순서의이 종류에 대해 궁금 해요 :이 비동기 개체 풀 구현은 안전합니까?
- 스레드 A - obtainObject()를
- 스레드 A가 - releaseObject() - 객체 수정
- 스레드 A (visibleState = 42라고 할 수 있습니다)
- 스레드 B - 관련이없는 무언가를하거나
- 스레드 B 다이 - - 객체를 수정 (말 visibleState = 1 수) obtainObject()는
- 스레드 A (그냥 발표 한 객체를 가져)
- 스레드 B - 인쇄 visibleState
- 스레드 B 개체 - releaseObject()를
스레드 A에서 변경이 가능한 상태 자체를 수정 한 B 후 B 스레드로 표시 될 수 있을까? (실제로는 발생하지 않지만, JLS/Javadoc이 이것을 보장하는지, 그리고 어떻게 보장되는지는 알 수 없습니다.)
필수 항목 만 보여주기 위해 아래 코드를 제거했습니다. 나는 물건을 만들기 위해 generification과 공장을 버렸다. 수영장에 의해 관리
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;
}
지금까지 가시성이 간다
실제로 대기열이 없습니다. –
firstObject에 대한 의견을 참조 하시겠습니까? 어쩌면 내 영어가 실패 하긴하지만, 하나의 연결된 목록을 합리적으로 '대기열'이라고 부를 수 있다고 생각합니다. – Durandal
아마도 대기열처럼 사용되지는 않습니다. 크기가 1 인 ['ArrayBlockingQueue'] (http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ArrayBlockingQueue.html)는 올바르게 사용하는 것이 훨씬 쉽습니다. 또는 [ 'SynchronousQueue'] (http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/SynchronousQueue.html)를 참조하십시오. –