栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JMM-可见性

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JMM-可见性

文章目录
  • Java内存模型
  • 代码解读
  • volatile(易变关键字)
  • synchronized区别

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 是不能保证指令重排的,它的有序是保证了多个线程之间的同步有序

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/425395.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号