Gibt es eine Möglichkeit, eine Art von Referenz zu implementieren, deren Wert mit einem anderen atomar ausgetauscht werden kann?
In Java haben wir AtomicReference
die mit einer lokalen Variablen vertauscht werden kann, aber nicht mit einer anderen AtomicReference
.
Das können Sie tun:
AtomicReference r1 = new AtomicReference("hello");
AtomicReference r2 = new AtomicReference("world");
und tauschen sie mit einer Kombination aus zwei Operationen aus:
r1.set(r2.getAndSet(r1.get()));
Dies führt jedoch dazu, dass sie sich in einem widersprüchlichen Zwischenzustand befinden, in dem beide "hello"
. Und selbst wenn man sie atomar austauschen könnte, könnte man sie (als Paar) immer noch nicht atomar lesen.
Was ich gerne tun würde, ist:
PairableAtomicReference r1 = new PairableAtomicReference("hello");
PairableAtomicReference r2 = new PairableAtomicReference("world");
AtomicRefPair rp = new AtomicRefPair(r1, r2);
entonces
Object[] oldVal, newVal;
do {
oldVal = rp.get();
newVal = new Object[] {oldVal[1], oldVal[0]};
} while (! rp.compareAndSet(oldVal, newVal));
um die Werte zu tauschen, und in einem anderen Thread:
AtomicRefPair otherRP = new AtomicRefPair(r1, r2);
System.out.println(Arrays.toString(otherRP.get()));
und seien Sie sicher, dass die Ausgabe entweder [hello, world]
o [world, hello]
.
Anmerkungen:
r1
yr2
für diesen Vorgang gepaart werden, aber es ist möglich, dass ein anderer Thread unabhängig davon, z.B.r1
und eine weiterer3
(leider bedeutet das, dass ich nicht diese Lösung .)- Es wird Hunderttausende dieser Referenzen geben, so dass eine globale
ReentrantLock
wäre ein großer Engpass. rp
yotherRP
werden nicht notwendigerweise von mehreren Threads gemeinsam genutzt, so dass ein einfaches Sperren nicht möglich ist. Sie könnten sein interniert Der interne Pool würde jedoch eine eigene Synchronisierung benötigen, was einen weiteren Engpass darstellen würde.- Ich habe hier nur Gruppen von 2 Referenzen gebildet, aber die Möglichkeit, 3 oder mehr zu gruppieren, wäre ein Bonus.
Ist es möglich, eine sperrfreie Version von AtomicRefPair
? Ich habe den Verdacht, dass das nicht der Fall ist, aber wenn nicht, gibt es vielleicht irgendwo einen Artikel, der erklärt, warum?
Verwandte Seiten : Wie tausche ich atomar 2 Ints in C#?