在多线程中我们常用的保证共享变量的方法有很多,现在我们介绍其中的一种,volatile,也是效率最高的一种。

   一 、volatile的意义:
            为了确保共享变量能被正确和一致的更新,字段被声明称volatile,java线程内存模型确保所有线程看到这个变量的值是一致的。volatile变量修饰符如果使用恰当的话,它比synchronize的使用和执行成本更低,因此它不会引起线程上下文的切换和调度。
 
   二 、如何保证所有线程看到的这个变量的值是一致的?
 源码中有这样一句, instance = new Singleton();说明这是一个单例,任何线程请求的都是这一个对象。生成汇编代码:

 在汇编代码中会出现 一个lock前缀,有这个前缀会发生两件事:
1.当前处理器的缓存行的数据都会写回到系统内存。
2.这个写回内存的操作会引起其他CPU缓存的该内存地址的数据无效。
为什么好多的都设64个字节,或是hash的一些默认空间设置成16个,原因与处理器结构有关,一般处理器缓存的额告诉缓存行时64个字节宽,换句话说他可以放16个对象,所以追加字节能优化性能。一些我们常见的java集合都是默认的设置空间为16。
  三 、 与Synchronize、lock的区别
       1.synchronize是一种机制,可加在方法上,也可以加载语句块上;lock是一个对象,多线程需要一个ReentrantLock才能实现锁机制。

       2.synchronize是托管给JVM管理的,lock是java代码写的控制锁的实现。
       3.synchronized采用的是悲观锁机制,线程获得的是独占锁,只能依靠阻塞来等待线程释放锁。而且CPU转换线程时上下文切换回引起新城竞争锁,使得效率降低。lock 采用的是乐观锁机制,乐观锁其实就是不加锁,一直去操作,失败就重新操作,直到成功为止,效率高很多。
4.当竞争不激烈的时候synchronize的性能好一点儿,但是当竞争激烈的时候lock的性能要很多。

四 、在JVM中锁是如何工作的:

         1.java对象头:hashcode,锁,分代年龄。在运行期间MarkWord 里存储的数据会随着锁标志位的变化而变化,可能变化为下面的数据:

多线程---再次认识volatile,Synchronize,lock的更多相关文章

  1. C#多线程-volatile、lock关键字

    volatile是C#中最简单的一种同步关键字,其意义是针对程序中一些敏感数据,不允许多线程同时访问,保证数据在任何访问时刻,最多有一个线程访问,以保证数据的完整性,虽与java中的synchroni ...

  2. 并行编程之多线程共享非volatile变量,会不会可能导致线程while死循环

    背景 大家都知道线程之间共享变量要用volatilekeyword.可是,假设不用volatile来标识,会不会导致线程死循环?比方以下的伪代码: static int flag = -1; void ...

  3. “全栈2019”Java多线程第二十七章:Lock获取lock/释放unlock锁

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  4. .NET多线程之线程安全,Lock(锁)、Monitor(同步访问)、LazyInitializer(延迟初始化)、Interlocked(原子操作)、static(静态)构造函数、volatile、

    1.什么是线程安全 线程安全是编程中的术语,指某个函数.函数库在多线程环境中被调用时,能够正确地处理多个线程之间的共享变量,使程序功能正确完成.一般来说,线程安全的函数应该为每个调用它的线程分配专门的 ...

  5. java多线程关键字volatile、lock、synchronized

    --------------------- 本文来自 旭日Follow_24 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/xuri24/article/detail ...

  6. Java多线程学习(六)Lock锁的使用

    系列文章传送门: Java多线程学习(二)synchronized关键字(1) Java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Java多 ...

  7. JMM内存模型+volatile+synchronized+lock

    硬件内存模型: Java内存模型: 每个线程都有一个工作内存,线程只可以修改自己工作内存中的数据,然后再同步回主内存,主内存由多个内存共享. 下面 8 个操作都是原子的,不可再分的: 1)  lock ...

  8. Java多线程编程(四)Lock的使用

    一.使用ReentrantLock类 在Java多线程中,可以使用synchronized关键字来实现线程之间的同步互斥,但ReentrantLock类也能达到同样的效果,并且在扩展功能上也更加强大, ...

  9. volatile与lock前缀指令

    前言 我们知道volatile关键字的作用是保证变量在多线程之间的可见性,它是java.util.concurrent包的核心,没有volatile就没有这么多的并发类给我们使用. 本文详细解读一下v ...

随机推荐

  1. 部署openfire到linux环境下

    1.java环境部署:具体参考 http://blog.csdn.net/gufachongyang02/article/details/45337379 2.ant环境部署: 具体参考 http:/ ...

  2. ffmpeg转码参数设置

    ffmpeg用了很久了,也没有想写点什么. 刚接触ffmpeg也是有大量的不理解的地方,不过慢慢的了解多了基本上都是可以使用的. 本文主要介绍如何使用ffmpeg.exe进行转码.编译好的ffmpeg ...

  3. DIV+CSS网页设计规范

    1.网页HTML代码最前面必须包括W3C声明,以便符合标准: 一般网页: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transition ...

  4. script 页面在指定位置加载

    <head> <script>  function load(){window.location="#workspaces"} </script> ...

  5. Spring Batch中job的启动,停止,放弃操作

    1,启动一个job 运行一个批处理任务至少有两点要求:一个 JobLauncher 和一个用来运行的 job .它们都包含了相同或是不同的 context .举例来说,从命令行来启动job,会为每一个 ...

  6. corntab被黑记录

    多出来的corntab 最近服务器经常出现负载过高的情况,经过运维排查,出现了一个corntab定时任务 不是开发的锅,别背 一开始运维认为是这个定时任务是我们开发的. 排查后,明确了服务器是被黑了. ...

  7. Android——Fragment过度动画分析一(转)

    Sliding Fragment 作者:小文字 出处:http://www.cnblogs.com/avenwu/   介绍:该案例为传统的Fragment增加了个性化的补间动画,其效果是原有frag ...

  8. Java 9中的 9个 新特性

    Java 9 中的 9个 新特性 java 7 2011发布,Java 8 2014发布,java9发布于2017年9月21日. 你可能已经听说过 Java 9 的模块系统,但是这个新版本还有许多其它 ...

  9. c# 利用反射清除事件

    控件的事件清除,除了-=,就只能依靠反射来执行了. /// <summary> /// 清除一个对象的某个事件所挂钩的delegate /// </summary> /// & ...

  10. JS事件对象,筋斗云导航练习,跟随鼠标练习,放大镜练习,进度条练习

    JS事件对象,筋斗云导航练习,跟随鼠标练习,放大镜练习,进度条练习 btn.onclick = function(event) { 语句 } 其中event就是事件对象,在这个方法中指向的对象是onc ...