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 }