• volatile 关键字 和 i++ 原子性


     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 }
  • 相关阅读:
    转:每个架构师都应该研究下康威定律
    使用OpenShiftFQ上外网
    关系模式设计
    数据库应用系统工程过程
    数据库系统
    四种常见 Git 工作流比较
    Git 进阶指南
    C#高性能TCP服务的多种实现方式
    浮动广告
    <span></span>
  • 原文地址:https://www.cnblogs.com/mozq/p/11335851.html
Copyright © 2020-2023  润新知