vloatile总结与synchronized对比
原文地址;https://www.cnblogs.com/xiaoxian1369/p/5411877.html
1、要使volatile变量提供理想的线程安全,必须同时满足以下两个条件:
1)、对变量的写操作不依赖于当前值;
2)、该变量没有包含在具有其他变量的不变式中。
第一个条件的限制使volatile变量不能用作线程安全的计数器。虽然增了操作(x++)看上去类似一个单独操作,实际上它是一个由读取-修改-写入操作序列组成的组合操作,必须以原子方式执行,而volatile不能提供必须的原子特性。实现正确的操作需要使x的值在操作期间保持不变,而volatile变量无法实现这一点。
2、一般共享变量是存放中主内存中,每一个线程都有一个属于自己的工作内存;当一个线程开始时,会将变量从主内存中拷贝一份副本放在自己的工作内存中,当使用时就高效多了,当有更改时,会回写到主内存中;当此时有多个线程对同一个共享变量进行操作时,只会操作属于自己线程的工作内存,之后回写到主内存中,相互之间不会有影响,故此时会有多线程安全问题。当该共享变量使用volatile修改时,一个线程对其进行了修改,则其回写到主内存时,会告知其他有该共享变量的副本,该副本已经失效了,故其他线程要使用该共享变量时,就会重新从主内存中拷贝一份副本到本线程中,以确保其线程内使用的都是最新的。
3、一般一个线程对变量的操作需要经历从主内存中读取Read--->加载到工作线程中load---->在工作线程中使用use--->该该共享变量进行赋值asign--->对该共享变量进行存储store--->将该共享变量回写到主内存中write。
4、一个共享变量被volatile修饰之后,就具备两层含义:
1)、保证不同线程对这个变量进行操作时的可见性,即一个线程修改了变量的值,该变量的新值对其他线程来说是立即可见的,但不保证操作的原子性;
2)、禁止进行指令重排。
5、使用synchronized可以保证变量修改的可见性和原子性,而volatile只能保证变量的可见性;synchronized是重量级的加锁,且开销大,而volatile是轻量级的无锁,且开销小
6、对于volatile修饰的引用类型(包括对象、数组等),其仅仅是保证引用地址的可见性,而不是引用指向的对象中元素的可见性。
7、一般64位的long和double是非原子操作的,是使用高低32位来进行赋值的,故这种64位的变量的赋值是非原子操作的,但在现代JVM中,都已保证该赋值操作是原子操作的。
8、关于指令重排,是指处理器为了提高处理速度将一些指令重新排序,但保证最终的结果是一致的,跟重排前的结果一样,这种是允许的;而volatile能防止指令重排,可以认为是在指令中增加了内存屏障,使在该volatile修饰的变量所属的指令,在没有使用之前,其前面的指令可以放在该指令之后,其后面的指令同样可以放在该指令之前,但有了该修改,则不会这样。
vloatile总结与synchronized对比的更多相关文章
- java多线程Lock接口简介使用与synchronized对比 多线程下篇(三)
前面的介绍中,对于显式锁的概念进行了简单介绍 显式锁的概念,是基于JDK层面的实现,是接口,通过这个接口可以实现同步访问 而不同于synchronized关键字,他是Java的内置特性,是基于JVM的 ...
- java ReentrantLock结合条件队列 实现生产者-消费者模式 以及ReentratLock和Synchronized对比
package reentrantlock; import java.util.ArrayList; public class ProviderAndConsumerTest { static Pro ...
- java 轻量级同步volatile关键字简介与可见性有序性与synchronized区别 多线程中篇(十二)
概念 JMM规范解决了线程安全的问题,主要三个方面:原子性.可见性.有序性,借助于synchronized关键字体现,可以有效地保障线程安全(前提是你正确运用) 之前说过,这三个特性并不一定需要全部同 ...
- java 线程安全 Lock
java.util.concurrent.locks 对于线程安全我们前面使用了synchronized关键字,对于线程的协作我们使用Object.wait()和Object.notify().在JD ...
- BAT美团滴滴java面试大纲(带答案版)之三:多线程Lock
继续面试大纲系列文章. 这是多线程的第二篇. 多线程就像武学中对的吸星大法,理解透了用好了可以得道成仙,俯瞰芸芸众生:而滥用则会遭其反噬. 在多线程编程中要渡的第二个“劫”,则是Lock.在很多时候, ...
- 理论篇-Java中一些零碎的知识点
1. Java中length,length方法,size方法区别 length属性:用于获取数组长度. length方法:用于获取字符串长度. size方法:用于获取泛型集合有多少个元素. 2. is ...
- BAT美团滴滴java面试大纲(带答案版)之四:多线程Lock
每天学习一点点 编程PDF电子书.视频教程免费下载:http://www.shitanlife.com/code 这是多线程的第二篇. 多线程就像武学中对的吸星大法,理解透了用好了可以得道成仙,俯瞰芸 ...
- Java多线程知识总结(一)
一.创建线程的三种方式: 创建线程的方式有三种,一是创建Thread实例,二是实现Runnable接口,三是实现Callable接口,Runnable接口和Callable接口的区别是一个无返回值,一 ...
- JAVA多线程提高八:线程锁技术
前面我们讲到了synchronized:那么这节就来将lock的功效. 一.locks相关类 锁相关的类都在包java.util.concurrent.locks下,有以下类和接口: |---Abst ...
随机推荐
- Atitit。Cas机制 软件开发 编程语言 无锁机制 java c# php
Atitit.Cas机制 软件开发 编程语言 无锁机制 java c# php 1. 为什么需要无锁操作1 2. 硬件支持 cas atomic2 3. 无锁编程(Lock-Free)就是在某些应用 ...
- GTS、GCK,GSR全称
GTS:Global 3-state buffer delay 全局使能,三态 GCK:Global Clock buffer delay 全局时钟 GSR:Global set/reset bu ...
- NHibernate Transformers.AliasToEntityMap 返回Hashtable
string query = "select a.CustomerName as CustomerName, b.ProductName as ProductName from Custom ...
- java设计模式 -------- 创建模式 之 抽象工厂模式
本文是自己学习所做笔记,欢迎转载,但请注明出处:http://blog.csdn.net/jesson20121020 工厂方法模式和抽象工厂模式不好区分清楚: 工厂方法模式特点: 1. 一个抽象产品 ...
- script
实例 链接一个外部脚本文件: <script type="text/javascript" src="myscripts.js"></scri ...
- Linux 5 下安装MySQL 5.6(RPM方式)
MySQL在很多领域被广泛使用,尤其是很多互联网企业,诸如腾讯,阿里等等.本文主要介绍在Linux 5下通过rpm方式来安装Mysql,这是比较简单的一种安装方式,具体详见下文. <MySQL权 ...
- Django中的request对象组成
if request.REQUEST.has_key('键值'): HttpRequest对象的属性 参考: 表 H-1. HttpRequest对象的属性 属 性 描述 path 表示提 ...
- sendmail发件人邮箱设定命令
sendmail发件人邮箱设定命令 以前就碰到过设置发件人后缀的方式,这次迁移服务器居然忘记,从头开始记录下 1:第一种方法,修改/etc/hosts,据说sendmail使用hosts里面的本地 ...
- Nginx HttpSubModule sub_filter模块的过滤功能
Nginx HttpSubModule sub_filter模块的过滤功能 发表于2年前(2013-08-05 10:39) 阅读(1481) | 评论(0) 0人收藏此文章, 我要收藏 赞0 5 ...
- poj 3666 河南省第七届程序设计D题(山区修路)
题目大意: 给定一个序列,以最小代价将其变成单调不增或单调不减序列,求最小的变动价值:需要用到离散化dp 状态转移方程: dp[i][j]=abs(j-w[i])+min(dp[i-1][k]);(k ...