JMM

131 阅读2分钟

Volatile是java虚拟机提供的轻量级同步机制。三大特性

  1. 保证可见性
package com.kuang.tvolatile; 
import java.util.concurrent.TimeUnit; 
public class JMMDemo { 
// 不加 volatile 程序就会死循环! // 加 volatile 可以保证可见性  
private volatile static int num = 0;
public static void main(String[] args) { /
    new Thread(()->{ 
        // 线程 1 对主内存的变化不知道的 
        while (num==0){ 
        } 
    }).start(); 
    try {
        TimeUnit.SECONDS.sleep(1); 
    } 
    catch (InterruptedException e) { 
        e.printStackTrace(); 
    }
    num = 1; 
    System.out.println(num); 
    } 
}
  1. 不保证原子性。使用原子类,可解决原子性问题.unsafe
  2. 禁止指令重排。 什么是指令重排:你写的程序,计算机并不是你写的那样去执行的。 源代码-->编译器优化重排-->指令并行也可以能会重排-->内存系统也会重排-->执行 处理器在进行指令重排的时候,考虑:数据之间的依赖性

JMM

JAVA内存模型。不存在的东西,完全是个概念约定

关于JMM一些同步的约定

  1. 线程解锁前:必须把共享变量立刻刷回主存
  2. 线程加锁前:必须读取主存中的最新值到工作内存中
  3. 加锁跟解锁是同一把锁 线程:工作内存 主内存

八种操作

lock(锁定) unlock(解锁) read(读取) load(载入) use(使用) assign(复制) store(存储) write(写入) 对称使用

CAS

比较当前工作内存中的值和主内存中的值,如果这个值是期望的则执行操作,否则一直循环 缺点:由于底层是自旋锁会浪费时间。一次性只能共保证一个共享变量的原子性。会存在ABA问题

ABA问题

当一个线程被另一个线程修改了CAS。就会产生ABA问题。 解决ABA原子引用:带版本号的原子操作。

公平锁:不能插队的锁。 非公平锁:可以插队的锁。(默认都是非公平锁) 可重入锁:递归锁。拿到了外面锁也就可以拿到里面的锁。自动获得 自旋锁:不断的去尝试,直到成功为止。spinLock