1 package com.mozq.multithread; 2 3 /** 4 * 深入理解Java虚拟机 volatile 关键字 和 i++ 原子性。 5 */ 6 public class VolatileTest { 7 public static volatile int race = 0; 8 9 private static final int THREADS_COUNT = 20; 10 11 public static void main(String[] args) { 12 Thread[] threads = new Thread[THREADS_COUNT]; 13 for(int i = 0; i < THREADS_COUNT; i++){ 14 threads[i] = new Thread(()-> {//自增 10000 次 15 for (int j = 0; j < 10000; j++) { 16 race++; 17 } 18 }); 19 threads[i].start(); 20 } 21 //等待所有线程执行完毕 22 for(int i = 0; i < THREADS_COUNT; i++){ 23 try { 24 threads[i].join(); 25 } catch (InterruptedException e) { 26 e.printStackTrace(); 27 } 28 } 29 30 System.out.println(race); 31 } 32 /* 33 javap -v VolatileTest.class 34 使用 javap 工具生成字节码指令信息,发现自增操作对应多条字节码指令,一条字节码至少对应一条机器指令,所以自增对应多条机器指令。 35 更严谨的说法应该验证自增操作和汇编指令间的对应关系。可以使用 PrintAssembly 工具生成对应汇编指令。 36 public static void increase(); 37 descriptor: ()V 38 flags: ACC_PUBLIC, ACC_STATIC 39 Code: 40 stack=2, locals=0, args_size=0 41 0: getstatic #2 // Field race:I 42 3: iconst_1 43 4: iadd 44 5: putstatic #2 // Field race:I 45 */ 46 }
1 package com.mozq.multithread; 2 3 import java.util.concurrent.BlockingQueue; 4 import java.util.concurrent.LinkedBlockingQueue; 5 import java.util.concurrent.atomic.AtomicReference; 6 import java.util.concurrent.locks.LockSupport; 7 // CAS自定义锁及模拟高并发测试 https://blog.csdn.net/LiuRenyou/article/details/92996001#CountDownLatch_54 8 public class ExclusiveLock { 9 AtomicReference<Thread> sign = new AtomicReference(); 10 BlockingQueue<Thread> waiter = new LinkedBlockingQueue(); 11 12 public void lock(){ 13 Thread thread = Thread.currentThread(); 14 while(!sign.compareAndSet(null,thread)){ 15 waiter.add(thread); 16 //这里不可以用wait notify,因为notify不能唤醒指定的线程,只能用LockSupport 17 LockSupport.park(); 18 waiter.remove(thread); 19 } 20 } 21 22 public void unlock(){ 23 if(sign.compareAndSet(Thread.currentThread(),null)){ 24 Object[] arrs = waiter.toArray(); 25 for (Object obj:arrs) { 26 LockSupport.unpark((Thread)obj); 27 } 28 } 29 } 30 }