java共享变量可见性问题

林与夕 2020-09-18 11:26:54
package volatilex;

public class VolatileMain {

private static boolean flag = false;

public static void main(String[] args) {
new Thread(() -> {
System.out.println("start");
while (!flag) {
}
System.out.println("run end");
}).start();
new Thread(() -> {
System.out.println("init begin");
init();
System.out.println("init end");
}).start();
}

private static void init() {
flag = true;
}

}

打印结果如下

start
init begin
init end
run end
...全文
6083 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
shy078 2020-09-25
  • 打赏
  • 举报
回复
可见性是线程1,线程2有自己的工作内存,工作内存与主内存交互,而变量存储在主内存中,所以变量flag对于线程1、线程2均是可见的。但是如果有一个线程修改了flag,且该flag不被volatile修饰,那么另一个线程就看不到最新的值,volatile最初的本意是这个。
flying_fish79 2020-09-24
  • 打赏
  • 举报
回复
System.out.println("start"); while (!flag) { } System.out.println("run end"); 这个判断的话,打印出来的这四行不论你ture还是false不都是这么打印的么
qybao 2020-09-18
  • 打赏
  • 举报
回复
你改成以下再试试

    private static boolean flag = false;
public static void main(String[] args) {
new Thread(() -> {
System.out.println("start");
while (!flag) {
}
System.out.println("run end");
}).start();
new Thread(() -> {
System.out.println("init begin");
try {Thread.sleep(10);} catch (Exception e) {} //这里睡眠一下,保证线程1进入while(!flag)循环
init();
System.out.println("init end");
}).start();
}

private static void init() {
flag = true;
}
qybao 2020-09-18
  • 打赏
  • 举报
回复
这是线程的随机性和代码的原子性造成的
线程1打印完start,能保证它会继续执行while(!flag)吗?也许刚打印完start,就切换到线程2执行了,线程2把flag改了,这时又切换到线程1继续执行,那while(!flag)当然就不成立了。
林与夕 2020-09-18
  • 打赏
  • 举报
回复
为什么不加上volatile也能可见?

62,625

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧