Java并发编程实战 学习笔记Day8

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

今天这篇笔记是关于Java内存模型是如何解决可见性和有序性导致的问题。

首先学习一下什么是Java内存模型

导致可见性的原因是缓存导致有序性的原因是编译优化那直接禁用掉缓存和编译优化就可以解决了但是这样我们的程序性能就大打折扣了。合理的方案就是按需禁用以及编译优化。

Java内存模型是个很复杂的规范可以从不同的视角来解读站在程序员的视角本质上可以理解为Java内存模型规范了JVM如何提供按需禁用缓存和编译优化的方法具体来说这些方法包括volatile、synchronized和final三个关键字以及六项Happens-Before规则。

使用volatile的困惑

volatile关键字在很多编程语言中都有它最原始的意义就是禁用CPU缓存。

在Java1.5之前使用volatile修饰只能解决该修饰变量的内存可见性问题只能保证这个变量的修饰可以立即被其他线程看到。在1.5版本的时候Java内存模型对volatile语义进行了增强。

Happens-Before规则

1.程序的顺序性规则

这条规则是指在一个线程中按照程序顺序前面的操作Happens-Before于后续的任意操作。

在新的内存模型中volatile周围的普通字段不能随便重排编译器生成字节码时会在volatile写操作的前面和后面分别插入内存屏障StoreStore屏障|volatile写|StoreLoad屏障其中StoreStore屏障禁止上面的普通写和下面的volatile写重排序StoreLoad屏障防止上面的volatile写与下面可能有的volatile读/写重排序。

2.volatile变量规则

对一个volatile变量的写操作先行发生于后面对这个变量的读操作这里的"后面"同样是指时间上的先后顺序。

3.传递性

这条规则是指如果 A Happens-Before B且 B Happens-Before C那么 A Happens-Before C。

4.管程中锁的规则

这条规则是指对一个锁的解锁 Happens-Before 于后续对这个锁的加锁。

管程是一种通用的同步原语在Java中指的就是synchronized管程中的锁在Java里是隐式实现的。

5.线程start()规则

这条规则是指主线程启动子线程后子线程可以看到主线程在启动子线程前的操作。

6.线程join()规则

这条是关于线程等待的。它是指主线程 A 等待子线程 B 完成主线程 A 通过调用子线程 B 的 join() 方法实现当子线程 B 完成后主线程 A 中 join() 方法返回主线程能够看到子线程的操作。当然所谓的“看到”指的是对共享变量的操作。

final

volatile为禁用缓存以及编译优化而final就是告诉编译器这个变量生而不变可以进行任意优化。

在1.5之后Java内存模型对final类型变量的重排进行了约束现在只要我们提供正确构造函数没有逸出就不会出现问题。

逸出 指的是对封装性的破坏.

学习来源极客时间

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Java