Ich verwendete AtomicReference, um AtomicInteger zu implementieren. Aber während des Testens merke ich sogar in einer Single-Threaded-Umgebung, dass die CAS-Operation stecken geblieben ist, sobald ihr Wert 128 erreicht hat. Mache ich etwas falsch oder gibt es einen Vorbehalt in AtomicReference (kann mit der CPU zusammenhängen)? Hier ist mein Code:Warum AtomicReference CAS false mit Wert 128 zurückgeben?
public class MyAtomInt {
private final AtomicReference<Integer> ref;
public MyAtomInt(int init) {
ref = new AtomicReference<Integer>(init);
}
public MyAtomInt() {
this(0);
}
public void inc() {
while (true) {
int oldVal = ref.get();
int nextVal = oldVal + 1;
boolean success = ref.compareAndSet(oldVal, nextVal); // false once oldVal = 128
if (success) {
return;
}
}
}
public int get() {
return ref.get();
}
static class Task implements Runnable {
private final MyAtomInt myAtomInt;
private final int incCount;
public Task(MyAtomInt myAtomInt, int cnt) {
this.myAtomInt = myAtomInt;
this.incCount = cnt;
}
@Override
public void run() {
for (int i = 0; i < incCount; ++i) {
myAtomInt.inc();
}
}
}
public static void main(String[] args) throws Exception {
MyAtomInt myAtomInt = new MyAtomInt();
ExecutorService exec = Executors.newSingleThreadExecutor();
exec.submit(new Task(new MyAtomInt(), 150)).get();
System.out.println(myAtomInt.get());
exec.shutdown();
}
}
Warum versuchen Sie, Ihren eigenen 'AtomicInteger' zu implementieren, wenn das JDK dies bietet? Befindest du dich auf einer Plattform, auf der es nicht unterstützt wird, oder ist das eine Übung? – Axel
Dies ist nur eine Übung, um sich mit dem java.util.concurrent.atomic-Paket vertraut zu machen, und ja, wir müssen definitiv die Räder nicht neu erfinden :) – Alan