在多线程中我们常用的保证共享变量的方法有很多,现在我们介绍其中的一种,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. Web通信

    客户在浏览器输入一个有效的url地址开始,浏览器会利用socket向url对应的web服务器发送一个TCP请求,这个请求成功一次就需要来回握三次手才能确定,成功以后,浏览器利用socket TCP连接 ...

  2. struts工作原理不错的解释___

    Struts 使用 Model 2 架构.Struts 的ActionServlet 控制导航流.其他Struts 类,比如Action, 用来访问业务逻辑类.当 ActionServlet 从容器接 ...

  3. list<PageData>传jsp隐藏域,在传回java

    java传jsp,代码如下: /**去修改页面 * @param * @throws Exception */ @RequestMapping(value="/goEdit") p ...

  4. bootstarp-table 设置隐藏列

    在做隐藏列的时候会发现一个问题. var settings = { url: ctx + "rollapply/list", pageSize: 10, queryParams: ...

  5. 使用Task代替ThreadPool和Thread

    转载:改善C#程序的建议9:使用Task代替ThreadPool和Thread 一:Task的优势 ThreadPool相比Thread来说具备了很多优势,但是ThreadPool却又存在一些使用上的 ...

  6. 电子印章在Odoo的实现步骤

    1. 首先用PS制作一个电子印章,具体步骤可参考 http://www.jb51.net/photoshop/173568.html 2. 给Odoo中的pdf添加印章的原理,就是利用Odoo的QWe ...

  7. [epoll]epoll理解

    转自:http://blog.51cto.com/yaocoder/888374 1. 流 首先我们来定义流的概念,一个流可以是文件,socket,pipe等等,可以进行I/O操作的内核对象,不管是文 ...

  8. gSoap的“error LNK2001: 无法解析的外部符号 _namespaces”解决方法

    错误 2 error LNK2001: 无法解析的外部符号 _namespaces 解决方法: 1. 在工程中定义 WITH_NONAMESPACES 宏 2.尝试 "#include &q ...

  9. CreateMutex和WaitForSingleObject组合的有关问题

    CreateMutex和WaitForSingleObject组合的问题在网上看见一个dll的代码,其中有这样几行 case   DLL_PROCESS_ATTACH:   ........ hmut ...

  10. webstorm 设置jsp支持ZenCoding

    setting -> File Type - html 里面增加*.jsp