Skip to content

Instantly share code, notes, and snippets.

@eupp
Created August 22, 2023 13:20
Show Gist options
  • Save eupp/0df5be68c3b9d4210e50a73f720a2658 to your computer and use it in GitHub Desktop.
Save eupp/0df5be68c3b9d4210e50a73f720a2658 to your computer and use it in GitHub Desktop.
Java Atomics API example
package org.example;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.util.concurrent.atomic.AtomicInteger;
public class Main {
static class Holder {
public volatile int atomic = 0;
}
public static void volatileExample() {
Holder holder = new Holder();
Thread[] threads = new Thread[2];
threads[0] = new Thread(() -> {
holder.atomic = 1;
});
threads[1] = new Thread(() -> {
int r = holder.atomic;
});
for (Thread thread: threads) {
thread.start();
}
for (Thread thread: threads) {
try {
thread.join();
} catch (InterruptedException ignored) {}
}
System.out.println("Result = " + holder.atomic);
}
public static void atomicsExample() {
AtomicInteger atomic = new AtomicInteger(0);
Thread[] threads = new Thread[3];
threads[0] = new Thread(() -> {
atomic.set(1); // Volatile memory order
atomic.setRelease(2); // Release memory order
atomic.setOpaque(3); // Opaque memory order
atomic.setPlain(4); // Plain memory order
});
threads[1] = new Thread(() -> {
atomic.get(); // Volatile memory order
atomic.getAcquire(); // Acquire memory order
atomic.getOpaque(); // Opaque memory order
atomic.getPlain(); // Plain memory order
});
threads[2] = new Thread(() -> {
atomic.compareAndSet(0, 1);
atomic.weakCompareAndSetVolatile(1, 2);
atomic.weakCompareAndSetAcquire(2, 3);
atomic.weakCompareAndSetRelease(3, 4);
atomic.weakCompareAndSetPlain(4, 5);
});
for (Thread thread: threads) {
thread.start();
}
for (Thread thread: threads) {
try {
thread.join();
} catch (InterruptedException ignored) {}
}
System.out.println("Result = " + atomic.get());
}
static VarHandle handle;
static {
try {
handle = MethodHandles.lookup().findVarHandle(Holder.class, "atomic", int.class);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public static void varHandleExample() {
Holder holder = new Holder();
Thread[] threads = new Thread[3];
threads[0] = new Thread(() -> {
handle.setVolatile(holder, 1); // Volatile memory order
handle.setRelease(holder, 2); // Release memory order
handle.setOpaque(holder, 3); // Opaque memory order
handle.set(holder, 4); // Plain memory order
});
threads[1] = new Thread(() -> {
handle.getVolatile(holder); // Volatile memory order
handle.getAcquire(holder); // Acquire memory order
handle.getOpaque(holder); // Opaque memory order
handle.get(holder); // Plain memory order
});
threads[2] = new Thread(() -> {
handle.weakCompareAndSet(holder, 0, 1); // Volatile memory order
handle.weakCompareAndSetAcquire(holder, 1, 2); // Acquire memory order
handle.weakCompareAndSetRelease(holder, 2, 3); // Release memory order
handle.weakCompareAndSetPlain(holder, 3, 4); // Plain memory order
});
for (Thread thread : threads) {
thread.start();
}
for (Thread thread : threads) {
try {
thread.join();
} catch (InterruptedException ignored) {
}
}
System.out.println("Result = " + holder.atomic);
}
public static void main(String[] args) {
volatileExample();
atomicsExample();
varHandleExample();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment