diff --git a/src/main/java/threaddemo/dataracing/CASByAtomicInteger.java b/src/main/java/threaddemo/dataracing/CASByAtomicInteger.java new file mode 100644 index 0000000..7dd4071 --- /dev/null +++ b/src/main/java/threaddemo/dataracing/CASByAtomicInteger.java @@ -0,0 +1,78 @@ +package threaddemo.dataracing; + +import java.util.concurrent.atomic.AtomicInteger; + +public class CASByAtomicInteger { + private final AtomicInteger counter = new AtomicInteger(0); + + // for aba problem + private final AtomicInteger unSafeCounter = new AtomicInteger(0); + + public static void main(String[] args) { + CASByAtomicInteger casByAtomicInteger = new CASByAtomicInteger(); + casByAtomicInteger.safeIncrementDemo(); + System.out.println("-------------------------"); + casByAtomicInteger.unsafeIncrementDemo(); + } + public void safeIncrementDemo() { + Thread t1 = new Thread(() -> { + for (int i = 0; i < 10000; i++) { + counter.incrementAndGet(); + } + }); + Thread t2 = new Thread(() -> { + for (int i = 0; i < 10000; i++) { + counter.incrementAndGet(); + } + }); + + t1.start(); + t2.start(); + try { + t1.join(); + t2.join(); + System.out.println(STR."counter: \{counter.get()}"); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + public void unsafeIncrementDemo() { + Thread t1 = new Thread(() -> { + int initValue = unSafeCounter.get(); + System.out.println(STR."Thread 1: Initial value = \{initValue}"); + + unSafeCounter.compareAndSet(0,20); + unSafeCounter.compareAndSet(20,0); + + System.out.println(STR."Thread 1: Final value = \{unSafeCounter.get()}"); + + },"t1"); + + Thread t2 = new Thread(() -> { + int value = unSafeCounter.get(); + try { + // 等待线程1完成 ABA 操作 + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("Thread 2: Initial value = " + value); + + // 尝试 CAS 操作 + boolean success = unSafeCounter.compareAndSet(0, 30); // A -> C + System.out.println(STR."Thread 2: CAS success = \{success}"); + System.out.println(STR."Thread 2: Final value = \{unSafeCounter.get()}"); + },"t2"); + + t1.start(); + t2.start(); + + try { + t1.join(); + t2.join(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } +}