Java 多线程 ⑦-内存可见性 || volatile || JMM || wait notify notifyAll

 这里是Themberfue

· 在上一节中,我们讨论了死锁的概念,产生的场景 ,产生的必要条件......


内存可见性 

· 我们先来看一段百度百科关于 "内存可见性"  的解释

· "内存可见性" 就是造成线程安全问题的原因之一

· 如果是单纯地看这段文字,可能会比较难读,我们通过一段代码来深入理解这个问题

public class Demo21 {
    public static int flag = 0;
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            while (flag == 0) {

            }
            System.out.println("t1线程结束");
        });

        Thread t2 = new Thread(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            flag = 1;
            System.out.println("t2线程结束");
        });

        t1.start();
        t2.start();
        t1.join();
        t2.join();
    }
}

· 这段不难读懂,t1 线程判断变量 flag 的改变情况,若为 0,则 t1 线程循环执行,若被修改后,则 t1 线程会立刻终止执行

· t2 线程执行修改变量 flag 的任务,但并非立刻执行修改的逻辑,而是1ms 后

· 这样的代码理论上并无问题,在 1s 后,两个线程都会结束

· 但实际运行后,你会发现虽然 t2 线程结束了,但是 t1 线程却迟迟没有结束,查看变量 flag 的值,也确实更改为了 1,但为什么 t1 线程没有结束呢?

· 众所周知,程序员之间的水平都是参差不平的

· 优化代码这件事本来就是很微妙的,程序都能跑,那我就懒得优化了,这绝对是大多数程序员的写照(但是,代码优化也是非常重要的事情,还是要注意的)

· 研究 JDK 的大佬们,就希望通过 编译器 或者 JVM 来给我们写出的代码自动优化,在对逻辑不变的前提下,对代码的结构进行一些小幅度的调整从而使代码更加高效的运行

· 这样的事看起来当然好,但是难免地会引发弊端,尤其是在编写多线程代码时,编译器 或者 JVM 的优化可能就会判断失误,导致逻辑理论上是正确的,但结果却大不尽人如意

·  "内存可见性" 就是由于 JVM 自动优化代码所造成的

· 我们先来了解汇编语言中的一个指令:"cmp" 本质是比较(compare)指令,通常用于控制程序流程(例如条件判断和分支),cmp 本质是一个隐式减法操作

while (flag == 0) {}

· 上述伪代码就是一个条件判断,在执行 "cmp" 指令之前,程序还得先执行 load 指令(在x86架构中是用 mov 指令执行类似的操作),

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值