热点新闻
Java多线程 - volatile 关键字
2023-07-06 13:25  浏览:1535  搜索引擎搜索“早勤网”
温馨提示:信息一旦丢失不一定找得到,请务必收藏信息以备急用!本站所有信息均是注册会员发布如遇到侵权请联系文章中的联系方式或客服删除!
联系我时,请说明是在早勤网看到的信息,谢谢。
展会发布 展会网站大全 报名观展合作 软文发布

首先看一个例子

package cn.lazyfennec.demo.example; import java.util.concurrent.TimeUnit; public class VisibilityDemo { public boolean flag = true; public static void main(String[] args) throws InterruptedException { VisibilityDemo demo = new VisibilityDemo(); System.out.println("代码开始了~~~~"); Thread thread = new Thread(new Runnable() { @Override public void run() { int i = 0; while(demo.flag) { i++; } System.out.println(i); } }); thread.start(); TimeUnit.SECONDS.sleep(2); demo.flag = false; System.out.println("flag 被置为 false 了"); } }

以上的代码,在不看运行结果的情况下,按照逻辑分析,最后的结果大致如下

代码开始了~~~~ flag 被置为 false 了 *** // 这里***表示某个值

但是实际的执行结果是这样的

代码开始了~~~~ flag 被置为 false 了 // 这里进入了死循环


volatile 关键字

  • 可见性问题
    让一个线程对共享变量的修改,能够及时的被其他线程看到。
  • Java内存模型规定:
    volatile 变量v的写入,与所有其他线程后续对 v 的读同步

要满足以上条件,volatile关键字需要有以下的功能

  1. 禁止缓存
    volatile变量的访问控制符会加个ACC_VOLATILE
    https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.5

  2. volatile 变量相关的指令不做重排序
    即JVM在进行编译的时候,正常情况下,会在JVM规定的规范内,对指令进行重排序,以提高运行效率(性能),而对于volatile修饰的内容,则不会进行重新排序。

  • 对于以上的问题,在flag变量前加入volatile关键字

public volatile boolean flag = true;

此时的执行结果

代码开始了~~~~ flag 被置为 false 了 30024084


扩展: Shared Variables 共享变量定义

可以在线程之间共享的内存称为共享内存或堆内存
所有实例字段静态字段数组元素都存储在堆内存中,这些字段和数组都是标题中提到的共享变量
冲突:如果至少有一个访问是写操作,那么对同一个变量的两次访问是冲突的。
这些能被多个线程访问的共享变量是内存模型规范的对象。

定义在: https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4.1


如果觉得有收获就点个赞吧,更多知识,请点击关注查看我的主页信息哦~

发布人:6504****    IP:117.173.23.***     举报/删稿
展会推荐
让朕来说2句
评论
收藏
点赞
转发