volatile和synchronized的区别
volatile和synchronized特点
首先需要理解线程安全的两个方面:执行控制和内存可见。
执行控制的目的是控制代码执行(顺序)及是否可以并发执行。
内存可见控制的是线程执行结果在内存中对其它线程的可见性。根据Java内存模型的实现,线程在具体执行时,会先拷贝主存数据到线程本地(CPU缓存),操作完成后再把结果从线程本地刷到主存。
synchronized关键字解决的是执行控制的问题,它会阻止其它线程获取当前对象的监控锁,这样就使得当前对象中被synchronized关键字保护的代码块无法被其它线程访问,也就无法并发执行。更重要的是,synchronized还会创建一个内存屏障,内存屏障指令保证了所有CPU操作结果都会直接刷到主存中,从而保证了操作的内存可见性,同时也使得先获得这个锁的线程的所有操作,都happens-before于随后获得这个锁的线程的操作。
volatile关键字解决的是内存可见性的问题,会使得所有对volatile变量的读写都会直接刷到主存,即保证了变量的可见性。这样就能满足一些对变量可见性有要求而对读取顺序没有要求的需求。
使用volatile关键字仅能实现对原始变量(如boolen、 short 、int 、long等)操作的原子性,但需要特别注意, volatile不能保证复合操作的原子性,即使只是i++,实际上也是由多个原子操作组成:read i; inc; write i,假如多个线程同时执行i++,volatile只能保证他们操作的i是同一块内存,但依然可能出现写入脏数据的情况。
在Java 5提供了原子数据类型atomic wrapper classes,对它们的increase之类的操作都是原子操作,不需要使用sychronized关键字。
对于volatile关键字,当且仅当满足以下所有条件时可使用:
1. 对变量的写入操作不依赖变量的当前值,或者你能确保只有单个线程更新变量的值。
2. 该变量没有包含在具有其他变量的不变式中。
volatile和synchronized的区别
- volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取; synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。
- volatile仅能使用在变量级别;synchronized则可以使用在变量、方法、和类级别的
- volatile仅能实现变量的修改可见性,不能保证原子性;而synchronized则可以保证变量的修改可见性和原子性
- volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞。
- volatile标记的变量不会被编译器优化;synchronized标记的变量可以被编译器优化
volatile和synchronized的区别的更多相关文章
- 多线程学习:Volatile与Synchronized的区别、什么是重排序
java线程的内存模型 java的线程内存模型中定义了每个线程都有一份自己的共享变量副本(本地内存),里面存放自己私有的数据,其他线程不能直接访问,而一些共享变量则存在主内存中,供所有线程访问. 上图 ...
- 多线程的指令重排问题:as-if-serial语义,happens-before语义;volatile关键字,volatile和synchronized的区别
一.指令重排问题 你写的代码有可能,根本没有按照你期望的顺序执行,因为编译器和 CPU 会尝试指令重排来让代码运行更高效,这就是指令重排. 1.1 虚拟机层面 我们都知道CPU执行指令的时候,访问内存 ...
- Volatile关键字&&DCL单例模式,volatile 和 synchronized 的区别
Volatile 英文翻译:易变的.可变的.不稳定的. 一.volatile 定义及用法 多个线程的工作内存彼此独立,互不可见,线程启动的时候,虚拟机为每个内存分配一块工作内存,不仅包含了线程内部定义 ...
- 【转】volatile和synchronized的区别
volatile和synchronized的区别 volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取: synchronized则是锁定当前变量,只有当前 ...
- volatile与synchronized的区别
1.锁提供了两种主要特性:互斥(mutual exclusion) 和可见性(visibility). 互斥即一次只允许一个线程持有某个特定的锁,因此可使用该特性实现对共享数据的协调访问协议,这样,一 ...
- java多线程中 volatile与synchronized的区别-阿里面试
volatile 与 synchronized 的比较(阿里面试官问的问题) ①volatile轻量级,只能修饰变量.synchronized重量级,还可修饰方法 ②volatile只能保证数据的可见 ...
- volatile和synchronized的区别和联系
volatile 它所修饰的变量不保留拷贝,直接访问主内存中的. 在Java内存模型中,有main memory,每个线程也有自己的memory (例如寄存器).为了性能,一个线程会在自己的mem ...
- volatile和synchronized的区别与联系[转]
volatile是一个变量修饰符,而synchronized是一个方法或块的修饰符.所以我们使用这两种关键字来指定三种简单的存取变量的方式. int i1; ...
- Java中的Volatile和synchronized的区别
Synchronized和Volatile四个不同点: 1.粒度不同,前者锁对象和类 ,后者针对变量2.syn阻塞,volatile线程不阻塞3.syn保证三大特性,volatile不保证原子性4.s ...
随机推荐
- LNMP安装,FastCGI说明
1.1.工作原理讲解说明 1. 用户请求的静态文件,由nginx服务器处理,根据静态的location配置进行处理 用户请求的动态文件,由php服务进行处理,根据动态的location配置进行处理 2 ...
- mysql 数据库磁盘占用量统计
查看某个表的磁盘占用量 select (data_length+index_length)/1024/1024 M from information_schema.tables where table ...
- python:HTMLTestRunner测试报告优化
之前的博客有介绍过python的单元测试框架unittest,基于其扩展的测试报告模块HTMLTestRunner,不过这个报告本身的界面看起来太丑... 趁着今天有时间,找了两个二次开发优化后的HT ...
- Java关键字(五)——this
this 也是Java中的一个关键字,在<Java编程思想>第四版第五章5.4小节对 this 关键字是这样介绍的: this 关键字只能在方法内部使用,表示对“调用方法的那个对象”的引用 ...
- 前后端分离的利器:fiddler的实用功能举例
# 前后端分离的利器:fiddler的实用功能举例 ##what's fiddler fiddler是一款代理软件,对于前后端分离开发非常重要.可以说,如果前端开发没有用上fiddler或类似软件,那 ...
- 使用redis实现生产者消费者模式
本次主要分享一下使用redis做缓存队列,实现生产者消费者模式. 首先先来看一下redis提供的列表操作接口.像ListRightPush就和符合队列先进先出的原则. 然后围绕这个列表已下单为例简要实 ...
- Python之Flask笔记
在这里先说一下最开始所经历的一些错误app=Flask(_name_),当初拼写的时候怎么都报错后来发现此处是两个'_' 配置文件 app.config.from_object(__name__) 在 ...
- Maven 安装和配置
一.Maven 简介 Maven 是一个强大的Java项目构建工具,类似.NET中的NuGet ,Node.js的NPM. 正如nuget.org ,Maven有一个中央仓库 maven.org,可以 ...
- Python学习第十四篇——类初步使用及面向对象思想
class Restaurant(): def __init__(self,restaurant_name,cuisine_type): self.name = restaurant_name sel ...
- 1177: LFX学橙啦!题解
问题如下:先给你一个含有N个整数的数组数组中的每一个元素只为1或者0而N的大小为1~100你可以删除一些元素(也可以选择不删除),使剩下的数组中,没有一个元素0在1后面出现.并且要使剩下的元素的数量最 ...