java的线程抽象内存模型中定义了每个线程都有一份自己的私有内存,里面存放自己私有的数据,其他线程不能直接访问,而一些共享数据则存在主内存中,供所有线程进行访问。
上图中,如果线程A和线程B要进行通信,就要经过主内存,比如线程B要获取线程A修改后的共享变量的值,要经过下面两步:
(1)、线程A修改自己的共享变量副本,并刷新到了主内存中。
(2)、线程B读取主内存中被A更新过的共享变量的值,同步到自己的共享变量副本中。

java多线程中的原子性、可见性、有序性

 (1)、原子性:是指线程的多个操作是一个整体,不能被分割,要么就不执行,要么就全部执行完,中间不能被打断。(2)、可见性:是指线程之间的可见性,就是一个线程修改后的结果,其他的线程能够立马知道。(3)、有序性:为了提高执行效率,java中的编译器和处理器可以对指令进行重新排序,重新排序会影响多线程并发的正确性,有序性就是要保证不进行重新排序(保证线程操作的执行顺序)。

volatile关键字的作用

其实volatile关键字的作用就是保证了可见性和有序性(不保证原子性),如果一个共享变量被volatile关键字修饰,那么如果一个线程修改了这个共享变量后,其他线程是立马可知的。为什么是这样的呢?比如,线程A修改了自己的共享变量副本,这时如果该共享变量没有被volatile修饰,那么本次修改不一定会马上将修改结果刷新到主存中,如果此时B去主存中读取共享变量的值,那么这个值就是没有被A修改之前的值。如果该共享变量被volatile修饰了,那么本次修改结果会强制立刻刷新到主存中,如果此时B去主存中读取共享变量的值,那么这个值就是被A修改之后的值了。
volatile能禁止指令重新排序,在指令重排序优化时,在volatile变量之前的指令不能在volatile之后执行,在volatile之后的指令也不能在volatile之前执行,所以它保证了有序性。

关于指令重排序:

instance = new Instance(); //7:
这句,这并非是一个原子操作,事实上在 JVM 中这句话大概做了下面 3 件事情。

memory = allocate();   //7.1:分配对象的内存空间ctorInstance(memory);  //7.2:初始化对象instance = memory;     //7.3:设置 instance 指向刚分配的内存地址

在JVM的即时编译器中存在指令重排序的优化。
  
也就是说上面的第二步和第三步的顺序是不能保证的,最终的执行顺序可能是 1-2-3 也可能是 1-3-2。如果是后者,则在 3 执行完毕、2 未执行之前,被线程二抢占了,这时 instance 已经是非 null 了(但却没有初始化),所以线程二会直接返回 instance,然后使用,然后顺理成章地报错。
  
再稍微解释一下,就是说,由于有一个『instance已经不为null但是仍没有完成初始化』的中间状态,而这个时候,如果有其他线程刚好运行到第一层if (instance ==null)这里,这里读取到的instance已经不为null了,所以就直接把这个中间状态的instance拿去用了,就会产生问题。这里的关键在于线程T1对instance的写操作没有完成,线程T2就执行了读操作。
  
对于代码三出现的问题,解决方案为:给instance的声明加上volatile关键字

synchronized关键字的作用

synchronized提供了同步锁的概念,被synchronized修饰的代码段可以防止被多个线程同时执行,必须一个线程把synchronized修饰的代码段都执行完毕了,其他的线程才能开始执行这段代码。
因为synchronized保证了在同一时刻,只能有一个线程执行同步代码块,所以执行同步代码块的时候相当于是单线程操作了,那么线程的可见性、原子性、有序性(线程之间的执行顺序)它都能保证了。

volatile关键字和synchronized关键字的区别

 (1)、volatile只能作用于变量,使用范围较小。synchronized可以用在变量、方法、类、同步代码块等,使用范围比较广。(2)、volatile只能保证可见性和有序性,不能保证原子性。而可见性、有序性、原子性synchronized都可以包证。(3)、volatile不会造成线程阻塞。synchronized可能会造成线程阻塞。

可见性是:

当A线程更改了,没有volatile 关键字的话,不会立马刷新到主存。那什么时候会刷新到主存? 是因为没有立马刷新到主存导致不可见,那么b线程没有使用公有变量都会从主存取吗?还是说只有volatile 才会这样?

ConcurrentLinkedDeque 实现多线程安全就是利用volatile 实现的,而不是synchronized

https://blog.csdn.net/weixin_37817685/article/details/80261549

Java synchronized 和 volatile 的区别相关推荐

  1. day 23-24 面试题:synchronized和volatile的区别;final,finally,finalize区别

    面试题: 1. synchronized和volatile的区别 2. final,finally,finalize区别 1. synchronized和volatile的区别 1.1 JVM内存模型 ...

  2. 既生synchronized,何生volatile (synchronized与volatile的区别)

    既生synchronized,何生volatile (synchronized与volatile的区别) 我们知道,synchronized和volatile两个关键字是Java并发编程中经常用到的两 ...

  3. java中二进制怎么说_面试常用:说清楚Java中synchronized和volatile的区别

    回顾一下两个关键字:synchronized和volatile 1.Java语言为了解决并发编程中存在的原子性.可见性和有序性问题,提供了一系列和并发处理相关的关键字,比如synchronized.v ...

  4. synchronized、volatile的区别

    synchronized可以作用于变量.实例方法.静态方法,volatile只作用于变量. 同一时刻只有一个线程能进入synchronized作用的代码,其他线程会阻塞.volatile不会阻塞. s ...

  5. Java基础学习总结(154)——Synchronized与Volatile、Synchronized与ReentrantLock概念及区别

    一.Synchronized与Volatile的区别 首先需要理解线程安全的两个方面:执行控制和内存可见.执行控制的目的是控制代码执行(顺序)及是否可以并发执行.内存可见控制的是线程执行结果在内存中对 ...

  6. synchronize和lock的区别 synchionzie与volatile的区别

    synchronized与Lock的区别 https://www.cnblogs.com/iyyy/p/7993788.html Lock和synchronized和volatile的区别和使用 ht ...

  7. java 轻量级同步volatile关键字简介与可见性有序性与synchronized区别 多线程中篇(十二)...

    概念 JMM规范解决了线程安全的问题,主要三个方面:原子性.可见性.有序性,借助于synchronized关键字体现,可以有效地保障线程安全(前提是你正确运用) 之前说过,这三个特性并不一定需要全部同 ...

  8. Java中synchronized和volatile有什么区别?

    Java中synchronized和volatile有什么区别? 相关内容 synchronized的问题 什么叫做不完整对象,这个怎么理解呢? 总结 ) 相关内容 1.Java语言为了解决并发编程中 ...

  9. Java之多线程里面的锁理解以及synchronized与Lock的区别

    一.宏观的说下锁的分类 1)锁分为乐观锁.悲观锁 悲观锁认为对于同一个数据的并发操作,一定是会发生修改的,哪怕没有修改,也会认为修改.因此对于同一个数据的并发操作,悲观锁采取加锁的形式.悲观的认为,不 ...

最新文章

  1. 判断TREE的某个节点是否是叶节点.
  2. 关于mysql设置varchar 字段的默认值''和null的区别,以及varchar和char的区别
  3. Sharepoint学习笔记—ECMAScript对象模型系列-- 7、获取和修改List的Lookup字段
  4. 程序猿们,别着急入手区块链,先给自己选好武林门派再练功不迟
  5. 浅谈:Spring Boot原理分析,切换内置web服务器,SpringBoot监听项目(使用springboot-admin),将springboot的项目打成war包
  6. 衡量人体健康的“十大新标杆”
  7. CentOS6最小化安装所需的常用软件(未完待更新)
  8. 【Python3网络爬虫开发实战】1.2.4-GeckoDriver的安装
  9. 三、Springmvc之Controller层方法返回值
  10. 金融评分卡项目—6.互联网金融业贷款申请评分卡介绍
  11. python爬虫:bs4搜索文档树
  12. 三星android手机工程模式,11款手机工程模式汇总 小编教你来验机
  13. 自动机器学习简述(AutoML)
  14. Python————办公自动化
  15. centos gedit 字体大小_【写作技巧】毕业论文格式要求及字体大小
  16. 蒜头君的藏书(映射)
  17. 王刚日记:在互联网第一次赚到钱
  18. Java面试宝典2018版
  19. 用css编写一个简单的旋转魔方
  20. 基于Python的OpenCV函数----imshow(winname, mat)【显示图片】

热门文章

  1. C++知识点26——使用C++标准库(常用的泛型算法1)
  2. syntaxerror是什么错误_【第1643期】自定义错误及扩展错误
  3. alexa api php,PHP使用Alexa API获取网站的Alexa排名例子
  4. springframework引入不进来_啥?你不知道JWT
  5. 【模板】RMQ问题—st表实现
  6. SpringBoot2.0之 个性化Banner
  7. Linux日常运维管理技巧
  8. linux shell (4) - Loop 循环
  9. 安装asp.net mvc4后mvc3项目编译报错
  10. corosync+pacemaker实现高可用(HA)集群(二)