文档章节

volatile和synchronized的区别

M
 MarinJ_Shao
发布于 06/25 00:26
字数 738
阅读 15
收藏 0

volatile和synchronized的区别

在讲这个之前需要先了解下JMM(Java memory Model :java内存模型):并发过程中如何处理可见性、原子性、有序性的问题--建立JMM模型

详情请看:https://baike.baidu.com/item/java内存模型/3399303

导致多线程开发比较困难的点有两点:

  1. 线程之间如何通信:
  • 共享内存:通过读写内存的公共状态进行隐式传递
  • 消息传递:通过wait()/notify()/notifyAll()等方式,通过发送消息进行显示传递
  1. 线程之间如何同步:
  • 在共享内存的并发模型中,同步是显示做的;synchronized
  • 在消息传递的并发模型中,由于消息的发送必须在消息接收之前,所以同步是隐式的。

说明:Java里面所有的实例域、静态域、数组元素都存储在堆内存中的,堆内存是在多线程之间共享的;局部变量、方法、定义参数或者异常处理不会在线程之间共享的。是否共享导致了内存可见性的问题。(多线程读写同一个文件,多读多写同步进行,会导致混乱) 从上图看线程A和线程B什么时候去同步和更新主内存的共享内存都是不确定的,不确定的因素导致线程安全和线程可见性问题。

 这时候引入volatile。
  • 对于申明了volatile的变量在写操作的时候,JVM向处理器发送一条lock前缀的指令,把这个变量所在缓存行的数据写回到系统内存(主内存);
  • 在多处理器的情况下,保证各个处理器缓存一致性的特点,就会实现缓存一致性协议。这里类似分布式情况下的多个数据库数据一致性、原子性。
  • 每个处理器都去主内存中去检测自己本地缓存中的数据是否过期了(地址修改了),若修改了标志数据失效,当处理器对数据修改的时候,会去主内存同步数据到本地内存。 volatile可以做到原子性、可见性。不能保证复合操作的原子性。优点:相对synchronized开销小。

而synchronized:可重入性、互斥性、可见性。基于JVM实现的 以上是简单的实例在javap指令下查看其java编译器生成的字节码(JVM层面操作,所以synchronized没有源码)。 monitorenter和monitorexit分别是进入监视器,退出监视器,类似加锁和解锁。需要进入锁才能执行后面的方法。

本文转载自:

共有 人打赏支持
M
粉丝 0
博文 11
码字总数 4616
作品 0
杭州
程序员
volatile 和 synchronized 的比较

1,volatile 它所修饰的变量不保留拷贝,直接访问主内存中的。 在 Java 内存模型中,有 main memory,每个线程也有自己的 memory (例如寄存器)。为了性能,一个线程会在自己的 memory 中保持...

几个栗子
2017/11/05
0
0
多线程学习笔记(十二)

volatile的作用是使变量在多个线程间可见 1.死循环 public class PrintInfo implements Runnable { } public class Run { PrintInfo printInfo = new PrintInfo();printInfo.printInfo();Sy......

scymore
2016/09/13
43
0
java 里面保留字volatile及其与synchronized的区别

最近在读java并发编程相关的书籍,蚂蚁金服团队的杰作,可以好好把java并发相关的内容好好研究一下 要理解volatile和synchronized的区别,首先还是需要来理解下java的内存模型 java内存模型 ...

十二缸帕萨特
2015/10/09
267
0
Volatile关键字详解

简介   在java中,每个线程有一块工作内存区,其中存放这被所有线程共享的主内存中变量值的拷贝。当线程执行时,它在自己的工作内存中操作这些变量。为了获取一个共享变量,一个线程先获取...

wangtx
2016/05/11
121
0
多线程并发的解决方案 volatile synchronized notify notifyAll wait关键字分析

1.ThreadLocal用法 在java中,如果一个变量需要被多个线程访问,可以使用volatile来声明它为“易变的”。而假如一个变量要被持有它的某个线程独享,在java中,它可以使用java.lang.ThreadLoc...

陈小扁
2016/03/09
26
0

没有更多内容

加载失败,请刷新页面

加载更多

C++ std::thread

C++11提供了std::thread类来表示一个多线程对象。 1,首先介绍一下std::this_thread命名空间: (1)std::this_thread::get_id():返回当前线程id (2)std::this_thread::yield():用户接口...

yepanl
24分钟前
1
0
Nignx缓存文件与动态文件自动均衡的配置

下面这段nginx的配置脚本的作用是,自动判断是否存在缓存文件,如果有优先输出缓存文件,不经过php,如果没有,则回到php去处理,同时生成缓存文件。 PHP框架是ThinkPHP,最后一个rewrite有关...

swingcoder
28分钟前
1
0
20180920 usermod命令与用户密码管理

命令 usermod usermod 命令的选项和 useradd 差不多。 一个用户可以属于多个组,但是gid只有一个;除了gid,其他的组(groups)叫做扩展组。 usermod -u 1010 username # 更改用户idusermod ...

野雪球
29分钟前
0
0
Java网络编程基础

1. 简单了解网络通信协议TCP/IP网络模型相关名词 应用层(HTTP,FTP,DNS等) 传输层(TCP,UDP) 网络层(IP,ICMP等) 链路层(驱动程序,接口等) 链路层:用于定义物理传输通道,通常是对...

江左煤郎
36分钟前
1
0
使用xtrabackup完成远程备份

转载收藏,以防丢失 需求 Can I backup remote databases from my local server02-27-2013, 06:17 AMHi, I am using mysqldump so far for taking daily backups of my Production datab......

阿dai
41分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部