有沒有什麼辦法可以實現一種參考類型的值可以與另一個原子交換?可能創建可以原子交換的AtomicReference?
在Java中,我們有AtomicReference
可與局部變量互換,但不與其他AtomicReference
。
你可以這樣做:
AtomicReference r1 = new AtomicReference("hello");
AtomicReference r2 = new AtomicReference("world");
,並有兩個操作的組合交換它們:
r1.set(r2.getAndSet(r1.get()));
但是,這使他們處於不一致的狀態之間,其中都包含"hello"
。同樣,即使你可以原子交換它們,你仍然無法以原子方式讀取它們(作爲一對)。
我想做些什麼可以做的是:
PairableAtomicReference r1 = new PairableAtomicReference("hello");
PairableAtomicReference r2 = new PairableAtomicReference("world");
AtomicRefPair rp = new AtomicRefPair(r1, r2);
然後
Object[] oldVal, newVal;
do {
oldVal = rp.get();
newVal = new Object[] {oldVal[1], oldVal[0]};
} while (! rp.compareAndSet(oldVal, newVal));
交換的價值,並在另一個線程:
AtomicRefPair otherRP = new AtomicRefPair(r1, r2);
System.out.println(Arrays.toString(otherRP.get()));
並確保輸出結果爲[hello, world]
或[world, hello]
。
注:
r1
和r2
配對進行此操作,但它可能是另一個線程將獨立配對,說r1
和另一r3
- 有(不幸的是,這意味着我不能使用this solution)。將有成千上萬的這些參考文獻,因此全球性的
ReentrantLock
將是一個主要的瓶頸。 rp
和otherRP
不一定在線程之間共享,所以只需鎖定它們將不起作用。他們可能是interned,但實習生池將需要自己的同步,這將是另一個瓶頸。- 我在這裏只做了2個參考組,但能夠組3或更多將是一個獎金。
是否可以實現無鎖版本AtomicRefPair
?我有一個預感,它不是,但如果沒有,那麼也許有一篇文章解釋了爲什麼?
相關:How do I atomically swap 2 ints in C#?
Guava中有一個Interner,它使用ConcurrentHashMap,所以爭用可以是平均任意小的。 – maaartinus 2011-01-25 22:44:27