咸鱼

咸鱼是以盐腌渍后,晒干的鱼

0%

Java内存模型

Java的内存模型(JMM)规定了所有的变量都是存在于 主内存(RAM) 当中的,而每个线程都有自己的工作内存或者本地内存,线程对变量的所有操作都必须在自己的工作内存中进行,而不能直接对主内存操作,并且每个线程都不能访问其他线程工作内存或者本地内存

比如,在某个线程中对变量 i 的复制操作 i=1,改线程必须在本地内存中对 i 进行修改之后才能将其写入 主内存 之中。

Java内存模型(JMM)三大特性

一、原子性

所有操作都执行或者都不执行

如何保证原子性?
JMM只保证了基本读取和赋值的原子性操作,其他的不保证,如果想要使得某些代码片段具备原子性,
需要使用关键字synchronized,或者JUC中的lock。

总结:volatile关键字不具备保证原子性的语义

二、有序性

程序代码在执行过程中的先后顺序(编译器优化会导致不是开发者写的顺序)
具有保证顺序性的语义

Java提供三种方式保证有序性:

  1. 使用volatile保证有序性
  2. 使用synchronized保证有序性
  3. 使用显式锁Lock来保证有序性

volatile 变量规则

对一个变量的写操作要早于对这个变量之后的读操作。

根据字面的意思来理解是,如果一个变量使用volatile关键字修饰,
一个线程对它进行读操作,一个线程对它进行写操作,那么写入操作肯定要先行发生于读操作

三、可见性

当一个线程对共享变量进行修改,那么另外的线程可以立刻看到修改后的最新值。

Java提供三种方式保证可见性:

  1. 使用关键字volatile,当一个变量被volatile修饰,对于共享资源的读操作直接在主内存中进行,
    当其他线程对该共享资源进行修改,会导致当前线程在工作内存中的共享资源失效,所以必须从主内
    存中再次获取,对于共享资源的写操作当然是先要修改工作内存,然后刷新到主内存。
  2. synchronized能保证可见性
  3. 通过JUC的显式锁也能保证可见性。

总结:volatile具有保证可见性的语义

volatile关键字深入解析

语义

被volatile修饰的实例变量或者类变量具备如下两层语义

  1. 保证不同线程之间对共享变量操作时的可见性(一个线程修改,另外一个线程立刻看到最新值)
  2. 禁止对指令进行重排序操作。

volatile使用场景

  1. 多线程之间变量的可见性
  2. 有序性