From 8d7598bd4ce4cc23c0f3ba71f5213d461fd6e07f Mon Sep 17 00:00:00 2001 From: Jason Lu Date: Wed, 26 Feb 2025 09:57:10 +0800 Subject: [PATCH] add demo for volatile add demo for gc --- src/main/java/jvm/gc/ReferenceCountingGC.java | 28 +++++++++ .../java/threaddemo/SafeVolatileDemo.java | 36 ++++++++++++ .../java/threaddemo/VolatileAtomicDemo.java | 57 +++++++++++++++++++ 3 files changed, 121 insertions(+) create mode 100644 src/main/java/jvm/gc/ReferenceCountingGC.java create mode 100644 src/main/java/threaddemo/SafeVolatileDemo.java create mode 100644 src/main/java/threaddemo/VolatileAtomicDemo.java diff --git a/src/main/java/jvm/gc/ReferenceCountingGC.java b/src/main/java/jvm/gc/ReferenceCountingGC.java new file mode 100644 index 0000000..f0dd688 --- /dev/null +++ b/src/main/java/jvm/gc/ReferenceCountingGC.java @@ -0,0 +1,28 @@ +package jvm.gc; + +public class ReferenceCountingGC { + + private ReferenceCountingGC referenceCountingGC; + + private int OneMB = 1024 * 1024; + + private byte[] bigSize = new byte[1 * OneMB]; + + public static void testGC() { + ReferenceCountingGC objA = new ReferenceCountingGC(); + ReferenceCountingGC objB = new ReferenceCountingGC(); + objA.referenceCountingGC = objB; + objB.referenceCountingGC = objA; + + objA = null; + objB = null; + System.gc(); + System.out.println("finish GC"); + } + + + + public static void main(String[] args) { + testGC(); + } +} diff --git a/src/main/java/threaddemo/SafeVolatileDemo.java b/src/main/java/threaddemo/SafeVolatileDemo.java new file mode 100644 index 0000000..0677c8b --- /dev/null +++ b/src/main/java/threaddemo/SafeVolatileDemo.java @@ -0,0 +1,36 @@ +package threaddemo; + +import java.util.concurrent.FutureTask; + +public class SafeVolatileDemo { + + private static volatile SafeVolatileDemo SafeVolatileDemo; + + private SafeVolatileDemo() {} + + public static SafeVolatileDemo getInstance() { + if (SafeVolatileDemo == null) { + synchronized (SafeVolatileDemo.class) { + if (SafeVolatileDemo == null) { + SafeVolatileDemo = new SafeVolatileDemo(); + } + } + } + return SafeVolatileDemo; + } + + public static void main(String[] args) { + FutureTask t1 = new FutureTask<>(() -> SafeVolatileDemo.getInstance()); + FutureTask t2 = new FutureTask<>(() -> SafeVolatileDemo.getInstance()); + + new Thread(t1).start(); + new Thread(t2).start(); + try { + SafeVolatileDemo d1 = t1.get(); + SafeVolatileDemo d2 = t2.get(); + System.out.println(d1 == d2); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/threaddemo/VolatileAtomicDemo.java b/src/main/java/threaddemo/VolatileAtomicDemo.java new file mode 100644 index 0000000..616ef90 --- /dev/null +++ b/src/main/java/threaddemo/VolatileAtomicDemo.java @@ -0,0 +1,57 @@ +package threaddemo; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.ReentrantLock; + +public class VolatileAtomicDemo { + // will not guarantee added to 10000 + public static volatile int inc = 0; + + public static int inc2 = 0; + + public static AtomicInteger inc3 = new AtomicInteger(0); + + public static int inc4 = 0; + public final ReentrantLock lock = new ReentrantLock(); + + public void increase() { + inc++; + inc3.getAndAdd(1); + } + + public synchronized void safeIncrease() { + inc2++; + } + + public void safeIncrease2() { + lock.lock(); + try { + inc4++; + } finally { + lock.unlock(); + } + } + + public static void main(String[] args) throws InterruptedException { + ExecutorService pool = Executors.newFixedThreadPool(10); + final VolatileAtomicDemo test = new VolatileAtomicDemo(); + for (int i = 0; i < 10; i++) { + pool.execute(() -> { + for (int j = 0; j < 1000; j++) { + test.increase(); + test.safeIncrease(); + test.safeIncrease2(); + } + }); + } + + Thread.sleep(1000L); + System.out.println(inc); + System.out.println(inc2); + System.out.println(inc3.get()); + System.out.println(inc4); + pool.shutdown(); + } +}