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. }

volatile 关键字 和 i++ 原子性的更多相关文章

  1. 全面理解Java内存模型(JMM)及volatile关键字(转载)

    关联文章: 深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型(@Annotation) 深入理解Java类加载器(ClassLoad ...

  2. 全面理解Java内存模型(JMM)及volatile关键字

    [版权申明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/72772461 出自[zejian ...

  3. 全面理解Java内存模型(JMM)及volatile关键字(转)

    原文地址:全面理解Java内存模型(JMM)及volatile关键字 关联文章: 深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型( ...

  4. Java多线程学习(三)volatile关键字

    转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79680693 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...

  5. 一起来看看java并发中volatile关键字的神奇之处

    并发编程中的三个概念: 1.原子性 在Java中,对基本数据类型的变量的读取和赋值操作是原子性操作,即这些操作是不可被中断的,要么执行,要么不执行. 2.可见性 对于可见性,Java提供了volati ...

  6. 【C# 线程】 volatile 关键字和Volatile类、Thread.VolatileRead|Thread.VolatileWrite 详细 完整

    overview 同步基元分为用户模式和内核模式 用户模式:Iterlocked.Exchange(互锁).SpinLocked(自旋锁).易变构造(volatile关键字.volatile类.Thr ...

  7. Java中的volatile关键字为什么不是不具有原子性

    Java中long赋值不是原子操作,因为先写32位,再写后32位,分两步操作,而AtomicLong赋值是原子操作,为什么?为什么volatile能替代简单的锁,却不能保证原子性?这里面涉及volat ...

  8. JUC 并发编程--05, Volatile关键字特性: 可见性, 不保证原子性,禁止指令重排, 代码证明过程. CAS了解么 , ABA怎么解决, 手写自旋锁和死锁

    问: 了解volatile关键字么? 答: 他是java 的关键字, 保证可见性, 不保证原子性, 禁止指令重排 问: 你说的这三个特性, 能写代码证明么? 答: .... 问: 听说过 CAS么 他 ...

  9. Java并发编程:volatile关键字解析

    Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在 ...

随机推荐

  1. spring cloud gateway网关启动报错:No qualifying bean of type 'org.springframework.web.reactive.DispatcherHandler'

    网关配置好后启动报错如下: org.springframework.context.ApplicationContextException: Unable to start web server; n ...

  2. 【2019年07月22日】A股最便宜的股票

    查看更多A股最便宜的股票:androidinvest.com/CNValueTop/ 便宜指数 = PE + PB + 股息 + ROE,四因子等权,数值越大代表越低估. 本策略只是根据最新的数据来选 ...

  3. hystrixDashboard(服务监控)

    1.新建项目 microservicecloud-consumer-hystrix-dashboard 2.yml文件 server: port: 9001 3.在pom.xml文件增加如下内容 &l ...

  4. SQL ------------- 最大与最小函数

    sql max()  函数  求最大值,可以查询汉字,字母,日期,数字 注意:字母和汉字按照 a-z 依次查找,第一个最大的就是需要的                    比如:有两个字母或汉字都是 ...

  5. Hbase put写入源码分析

    今天有空闲时间看一下HBASE的写入代码 MutiAction类,是一个action的container,包括get . put. delete.并且是根据region name分组的.其中核心的就是 ...

  6. 转 Java jar (SpringBoot Jar)转为win可执行的exe程序

    原文链接:http://voidm.com/2018/12/29/java-jar-transform-exe/打包Jar工程 将java项目打包成jar工程,可以是文章以SpringBoot为例po ...

  7. Win10 CompatTelRunner.exe占用磁盘高的解决办法

    (1)在运行里输入  taskschd.msc, 打开windows计划任务 (2)参考下图在Application Experience下,1,2,3,4步骤,把所有带有 “CompatTelRun ...

  8. SVN服务端安装和仓库的创建

    1.安装SVN服务端 双击运行: 点击[next] 勾上复选框,点击[next] 使用默认选项,点击[next] 点击[Standard Edition]建议端口号不用443,因为Vmware占用了, ...

  9. mac pro使用2K(2056*1440)设置屏幕解决方法

    参考: https://www.jianshu.com/p/40cee8ab3d0f https://www.zhihu.com/question/35300978 在点击ok后,发现并不能保存.或者 ...

  10. saltstack的简单搭建

    环境; centos 7     192.168.10.10    master centos 7     192.168.10.129  minion 1.为了方便关闭防火墙 [root@local ...