线程安全、内存可见性问题与sychronized、volatile关键字

线程安全问题

  线程安全是线程同步问题。
在这里插入图片描述
图中是一个非常典型的读写不同步的问题,线程A的写操作没有被B及时看见,所以B的读写数据均为异常的。
  线程安全问题最常见的解决方案就是给共享变量加synchronized锁。

内存可见性问题

  java内存模型如图所示。当线程工作时,将主线程中的变量复制到自己的工作内存中,线程读写实际是操作自己工作内存中的变量。
在这里插入图片描述
实际工作时线程的工作内存:
在这里插入图片描述
  图片展示的是一个双核CPU架构,每个核都有自己的一级缓存,有点有二级缓存。
  内存可见性问题的出现:
1、当A读取数据时,回先在缓存中查找,若缓存中没有对应的数据则到主内存中查找并将数据保存到缓存中。
2、当B对同一个共享变量进行写操作时,会将数据加载到自己的缓存中,并进行写操作,同时将新的值写到主内存中。
3、A再对同一个数据进行写或读操作时,会在缓存中命中,不会再从主内存中查找,因此B对数据的修改对于A来说是不可见的。
解决共享变量不可见问题的方法是使用volatile关键字。

synchronize

  synchronize关键字可以获取共享变量的监视器锁。synchronize的内存语义是把synchronize块内用到的变量从线程的工作内存中清除,这样使用变量时就不会在工作内存中获取,而会从主内存中获取,因此synchronize能解决内存可见性问题。另外,synchronize是一种原子性的锁,所以能用于实现原子性操作。
  synchronize的使用会导致上下文切换,这会带来线程调度的开销。

volatile

  当一个变量被volatile修饰时,对共享变量的读写将会在主内存中进行,保证了内存可见性。另外,volatile并不能保证操作的原子性,不能解决前面提到的线程同步的安全问题。
  使用volatile关键字的情形:
1、写入变量不依赖它的当前值时。
2、读写变量没有加锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值