volatile与sy_面试中问到synchronized与volatile的区别

面试的时候经常问到 synchronized与volatile的区别的区别,你可能会奇怪他俩有什么关系吗,如果我觉着关系不大,但是又不能直接说,只能回答他们的共性和区别就ok了

多线程只有保证如下基本特性时才能保证安全:

可见性:线程都是基于cpu的运算,cpu有缓冲区,所以每次在计算的时候都会把数据加载到缓冲区中计算,那计算好的数据最终被会写到主存中,但是有时间差,没有synchronized或者volatile修饰,那么下一个线程读取的时候,读到的数据就有可能是修改前的数据。加上synchronized或者volatile,在该线程释放的时候会把数据写回主存。

主存简单理解为,内存的堆区,声明的属性或new的对象大部分都在堆中。

原子性:就好比你在思考一件事情,不愿意被其他事情打扰一样,线程的原子性也是如此,在执行一段逻辑的时候,也不希望被其他线程干预。多个线程同时请求同一资源或者代码块,这时候对资源或者代码加上synchronized,表示此时只有一个线程能够拿到锁,其他线程只能等待它被释放才能进行下一轮争夺。

有序性或者叫做禁止指令重排序:

处理器为了提高程序运行效率,可能会对输入代码进行优化,所以有可能会调整语句的执行顺序,但是它会保证最终结果的正确性。这种正确性只保证单线程里是没问题的。

int x =1 @1

int y=1;@2

x+y;@3

在处理的过程中可能会按照:@1-->@2-->@3

或者按照 @2-->@1-->@3的执行顺序,但是最终结果都是x+y=2;

int x =1; @1

volatile int y=1;@2

x+y;@3

那他的执行顺序只能是:@1-->@2-->@3

多线程重排序带来的问题:如下代码,如果线程A中发生了重排序,先执行的是inited = true;那么线程B发现inited已经被初始化为true了,那么user就不可能被初始化 ;

线程A中

textA(){

user = loadUser();

inited = true;

}

线程B中

textB(){

if (inited) {

print(user.getId());

}

}

synchronized主要特性:

修饰范围:可以是变量,可以方法。静态和非静态在锁的范围上会有区别。暂时不在这里讲了,后续分几篇专门讲锁。

上述三个特性都有即 可见性;原子性;有序性;

volatile主要特性:

修饰范围:只能是变量;

特性:

可见性;有序性或者叫做禁止指令重排序:不具有原子性;比如i++ 看上去是原子操作,其实并不是,而是分了两部分执行。

如果觉着写的不好请多指教,如果觉着对你有帮助请多关注哈

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值