有没有什么办法可以实现一种参考类型的值可以与另一个原子交换?可能创建可以原子交换的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