当前位置: 首页 > news >正文

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. 该变量没有包含在具有其他变量的不变式中。
  • 1
  • 2
  • 3

volatile和synchronized的区别

  1. volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取; synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。
  2. volatile仅能使用在变量级别;synchronized则可以使用在变量、方法、和类级别的
  3. volatile仅能实现变量的修改可见性,不能保证原子性;而synchronized则可以保证变量的修改可见性和原子性
  4. volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞。
  5. volatile标记的变量不会被编译器优化;synchronized标记的变量可以被编译器优化

转载于:https://www.cnblogs.com/xxj-bigshow/p/7611519.html

相关文章:

  • 全国省市数据库 access 版
  • CodeSmith模板引擎系列-目录
  • 分布式术语
  • SQL中truncate table和delete的区别
  • Ruby on Rails (ROR)类书籍下载地址及其他(整理)
  • sql server 2005卸载后重装显示sql server database services和工作站组件、联机丛书和开发工具安装失败...
  • xargs中的参数位置
  • 解读:大数据分析及其数据来源
  • general error c101008d: Failed to write the updated manifest to the resource of file
  • 容器如何访问外部世界?- 每天5分钟玩转 Docker 容器技术
  • 使用cookies实现浏览历史记录功能
  • 字符串类型内建方法归纳总结
  • 【随笔】也随便说说隐私的事情
  • Android MVC模式
  • 诗歌rails 之bundle
  • [PHP内核探索]PHP中的哈希表
  • 【笔记】你不知道的JS读书笔记——Promise
  • 2018一半小结一波
  • angular组件开发
  • CentOS7 安装JDK
  • Cookie 在前端中的实践
  • ES6之路之模块详解
  • gf框架之分页模块(五) - 自定义分页
  • golang 发送GET和POST示例
  • IIS 10 PHP CGI 设置 PHP_INI_SCAN_DIR
  • javascript面向对象之创建对象
  • JS 面试题总结
  • k8s如何管理Pod
  • macOS 中 shell 创建文件夹及文件并 VS Code 打开
  • Node项目之评分系统(二)- 数据库设计
  • Python 使用 Tornado 框架实现 WebHook 自动部署 Git 项目
  • windows下mongoDB的环境配置
  • 闭包--闭包之tab栏切换(四)
  • 服务器从安装到部署全过程(二)
  • 深度解析利用ES6进行Promise封装总结
  • 微信小程序开发问题汇总
  • 微信小程序实战练习(仿五洲到家微信版)
  • 携程小程序初体验
  • 一个项目push到多个远程Git仓库
  • 硬币翻转问题,区间操作
  • Semaphore
  • #gStore-weekly | gStore最新版本1.0之三角形计数函数的使用
  • #我与Java虚拟机的故事#连载12:一本书带我深入Java领域
  • (1)Android开发优化---------UI优化
  • (13)Latex:基于ΤΕΧ的自动排版系统——写论文必备
  • (Redis使用系列) Springboot 使用redis实现接口幂等性拦截 十一
  • (论文阅读31/100)Stacked hourglass networks for human pose estimation
  • (论文阅读40-45)图像描述1
  • (删)Java线程同步实现一:synchronzied和wait()/notify()
  • (十)DDRC架构组成、效率Efficiency及功能实现
  • (十三)Java springcloud B2B2C o2o多用户商城 springcloud架构 - SSO单点登录之OAuth2.0 根据token获取用户信息(4)...
  • (转)Oracle 9i 数据库设计指引全集(1)
  • .Mobi域名介绍
  • .NET MVC第五章、模型绑定获取表单数据
  • .Net+SQL Server企业应用性能优化笔记4——精确查找瓶颈