JUC并发编程(面试3)

p160
初探JMM内存模型
结合volatile实现线程优雅停止
有序性
volatile如何保证可见性
CAS


JMM内存模型

概念:
JMM 即 Java Memory Model,它定义了主存、工作内存抽象概念,底层对应着 CPU 寄存器、缓存、硬件内存、CPU 指令优化等。

JMM 体现在以下几个方面:

  • 原子性 - 保证指令不会受到线程上下文切换的影响 (synchronized,lock)
  • 可见性 - 保证指令不会受 cpu 缓存的影响 (synchronized,lock,volatile)
  • 有序性 - 保证指令不会受 cpu 指令并行优化的影响 (synchronized,lock,volatile)
    注意:synchronized , lock虽不能禁止指令重排,但能保证有序性.

可见性案例:

//退不出的循环
static boolean run = true;
public static void main(String[] args) throws InterruptedException {
 Thread t = new Thread(()->{
 while(run){
 // ....
 }
 });
 t.start();
 sleep(1);
 run = false; // 线程t不会如预想的停下来
}

正确做法static volatile boolean run = true;

注意: synchronized 语句块既可以保证代码块的原子性也同时保证代码块内变量的可见性。但缺点是synchronized 是属于重量级操作,性能相对更低。

如果实际中的情况是只有一个线程在写操作,多个线程读操作,适合用volatile。


结合volatile实现线程优雅停止
在这里插入图片描述



有序性

为什么要保证有序性:

为了提高cpu的执行效率,jvm会优化指令的执行顺序。在单线程的情况下,这样是没有问题的。但是在多线程的情况下就会出现安全性问题。



volatile如何保证可见性

  • 对volatile变量的写指令之后会加入写屏障。
    当被对volatile修饰的共享变量被修改后,会立刻同步到主存。
  • 对volatile变量的读指令之前会加入读屏障。
    当要获取被volatile修饰的共享变量时,会直接读取主存中的数据。


CAS 参考链接

概念:CAS又叫**“比较并交换(compare and set)”,CAS是一种基于乐观锁的实现**,他的目的是通过不加锁的方式来对共享资源的保护。CAS的基本思想是,将工作内存中旧的预期值与主存中的值进行比较,如果相同,则认为主存中的值没有被修改,那么就将工作内存中的新值更新给主存,并且比较和更新的这两个操作是一个原子的整体,这就保证同一时间只有一个线程更新成功。但是有一个问题,假如有一个线程对主存的共享资源进行了更新,但是并没有及时更新主存,那么比较就会出问题,因为CAS并不能够保证可见性。CAS操作需要volatile的支持,所以二者常常配合使用来解决并发线程的安全性问题。

CAS适用于线程数少于CPU核心数的情况。


Java中的13个原子操作类 跳转链接

使用原子的方式更新基本类型,Atomic包提供了以下3个类。

  • AtomicBoolean:原子更新布尔类型。
  • AtomicInteger:原子更新整型。
  • AtomicLong:原子更新长整型。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值