JMM-可见性

Java内存模型

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

  • 原子性 - 保证指令不会受到线程上下文切换的影响
  • 可见性 - 保证指令不会受 cpu 缓存的影响
  • 有序性 - 保证指令不会受 cpu 指令并行优化的影响

代码解读

@Slf4j
public class Test09 {

    static boolean flag = true;

    public static void main(String[] args) {
        new Thread(() -> {
            while (flag) {
				// 不能执行打印方法,如果使用了不能体现线程不可见,空着就行
            }
        }, "t1").start();

        // 主线程等子线程进入循环后改变flag,但不会影响子线程死循环,因为线程之间存在不可见性(线程有着自己的存储空间,为了性能)
        try {
            sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        log.info("主线程修改标志位");
        flag = false;
    }

}

结果子线程会死循环

  • 解决方法

用volatile修饰flag,子线程的每一次循环就不会从缓存中获取值,而是从主存中获取已经被主线程修改过的值

volatile static boolean flag = true;

volatile(易变关键字)

它可以用来修饰成员变量和静态成员变量,他可以避免线程从自己的工作缓存中查找变量的值,必须到主存中获取它的值,线程操作 volatile 变量都是直接操作主存

不能保证原子性,仅用在一个写线程,多个读线程的情况,如果多个线程写(i++问题),是不能防止指令交错的,还是会存在线程安全问题。


synchronized区别

synchronized 语句块既可以保证代码块的原子性,也同时保证代码块内变量的可见性。但缺点是
synchronized 是属于重量级操作,性能相对更低,synchronized 是不能保证指令重排的,它的有序是保证了多个线程之间的同步有序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值