java 中 volatile与synchronized的区别

一、Java并发编程的三个概念
  1. 原子性: 一个操作或者多个操作要么都操作成功要么都失败。
    例如:A转账B 100元,A账号扣100,B账号加100。这两个操作必须保证原子性。否则账户就有可能出现问题。
  2. 有序性:代码执行的顺序。
    JVM在执行编译后的代码,为了提高代码运行效率,会对代码重新排序。不一定是按照代码一行一行执行。
    例如:
int i = 10;// 1
int j = 100;//2
i = 100;// 3
j = 10;// 4
编译后,代码执行顺序可能是 1324,也有可能是2413。
  1. 可见性:当多个线程同时访问一个变量时,一个线程改变了变量的值。其它线程能看到改变后的值。
    Java内存模型规定所有的变量都是存在主存当中(类似于前面说的物理内存),每个线程都有自己的工作内存(类似于前面的高速缓存)。线程对变量的所有操作都必须在工作内存中进行,而不能直接对主存进行操作。并且每个线程不能访问其他线程的工作内存
二、volatile

volatile 只能保证操作的可见性和部分有序性。

  1. 可见性
volatile boolean stop = false;
// Thread 1
while(!ready){
	doSomethings();
}
// Thread2
if(condition) {
	stop = true;
}

如果不使用volatile变量,那么线程1可能永远不会停止。因为虽然线程2将stop的值改成了true,但是线程1可能还在读取线程工作区中stop值,这个值可能还是false;使用了volatile后ready的值改变后线程1工作区中的stop值会失效,然后重新从主内存中读取新的值。

  1. 部分有序性
volatile int i  =0;

int j = 0; // 1
int k = 0;// 2
i = 1;// 3
j = 1;// 4
k = 1;// 5

在这里操作3 Java会设置一个内存屏障,禁止指令重新排序:操作4,5 不会在操作3之前执行,操作1、2也不会在操作3之后执行。但是1,2的顺序可能重新排序(操作4,5同理)

三、synchronized

synchronized可以保持操作的原子性和可见性,synchronized会锁定变量,使其它线程不能访问此变量,只有当代码块执行完成,释放锁后其它线程才能操作此变量。
但是synchronized中代码块不能保证是有序的。而且这里要注意一下,synchronized锁定的不是代码块,而是synchronized括号中的变量,如果在非静态方法上则锁定的是this;如果是静态方法,锁定的对象是当前类的class对象

参考文档

https://www.cnblogs.com/dolphin0520/p/3920373.html
https://blog.csdn.net/qq_33173608/article/details/88202474

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值