请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

老师,为什么线程1中的while循环不会结束?

public class YuanThread {

private Boolean flag = true;

public void refresh() {
    System.out.println(Thread.currentThread().getName() + "refresh flag");
    flag = false;
}

public void forS() {
    System.out.println(Thread.currentThread().getName() + "开始执行");

    int i = 0;
    while (flag) {
        i++;
        // System.out.println();
        // sleep(100000);
        // sleep(1000);
    }
    System.out.println(Thread.currentThread().getName() + "跳出循环i=" + i);
}

public static void main(String[] args) {
    YuanThread yuanThread = new YuanThread();
    new Thread(() -> {
        yuanThread.forS();
    }, "thread1").start();


    try {
        Thread.sleep(2000);
        new Thread(() -> {
            yuanThread.refresh();
        }, "thread2").start();


    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

public static void sleep(long interval) {
    long start = System.nanoTime();
    long end;
    do {
        end = System.nanoTime();
    } while (start + interval > end);
}

}

i++ 下面增加不同耗时的操作,则有可能使循环结束。为什么thread1没有及时获取到thread2修改过的值呢?thread1的工作内存中的flag何时才能被刷新?

正在回答 回答被采纳积分+3

1回答

Jimin 2021-01-17 13:31:27

你好,要保证各个线程都能读到最新的值,要使用volatile,每次强制读取最新的值

0 回复 有任何疑惑可以回复我~
  • 提问者 奥观海同志 #1
    我知道用volatile可以获取到最新的值,我是想知道:
    1、一个线程在工作内存中修改过的值何时被刷新到主存?
    2、刷新到主存后、何时会同步到其他线程的工作内存中?
    
    谢谢
    回复 有任何疑惑可以回复我~ 2021-01-18 22:52:44
  • Jimin 回复 提问者 奥观海同志 #2
    你好,使用volatile修饰变量,每次读变量时都会强制更新,相当于直接从主存里读取最新的值
    回复 有任何疑惑可以回复我~ 2021-01-19 10:03:47
  • 提问者 奥观海同志 回复 Jimin #3
    老师 ,如果不用volatile的话:
    1、一个线程在工作内存中修改过的值何时被刷新到主存?
    2、刷新到主存后、何时会同步到其他线程的工作内存中?
    
    因为例子中不使用volatile的情况下,while循环体内的代码执行时间的长短,决定了循环能否break。i++运行时间过短、循环中的flag拿到的永远是true。循环永不跳出。如果i++下面加一行System。out。println(1)、循环却可以拿到flag为false,从而跳出循环。这种现象太奇怪了。
    回复 有任何疑惑可以回复我~ 2021-01-20 22:38:25
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信