开发者社区> 问答> 正文

一个java多线程的问题

为什么代码中线程VolatileExample 不会终止

public class VolatileExample extends Thread{
    private static boolean flag = false;
    @Override
    public void run() {
        while (!flag) {
            //System.out.println(1);
        }
    }
    public static void main(String[] args) throws InterruptedException {
        VolatileExample v = new VolatileExample();
        v.start();
        Thread.sleep(1000);
        flag = true;

    }
}

public class VolatileExample extends Thread{
    private static boolean flag = false;

    @Override
    public void run() {
        while (!flag) {
            System.out.println(1);
        }
    }
    public static void main(String[] args) throws InterruptedException {
        VolatileExample v = new VolatileExample();
        v.start();
        Thread.sleep(1000);
        flag = true;

    }
}

却可以正常终止。
还有这样

public class VolatileExample extends Thread{
    private static volatile boolean flag = false;

    @Override
    public void run() {
        while (!flag) {
            //System.out.println(1);
        }
    }
    public static void main(String[] args) throws InterruptedException {
        VolatileExample v = new VolatileExample();
        v.start();
        Thread.sleep(1000);
        flag = true;

    }
}

线程也可以正常终止。

展开
收起
蛮大人123 2016-03-19 17:24:32 2364 0
1 条回答
写回答
取消 提交回答
  • 我说我不帅他们就打我,还说我虚伪

    while(!flag) 是一个死循环这毋庸置疑了。
    第二个类,容易理解吧,执行System.out.println,CPU有机会在时间分片间隙,及时获得flag的值,使循环退出;
    第一个类,表面上看起来每次都死锁,但实际上是while{}中间没有任何指令被执行,那么他的时间分片很紧密,很难释放CPU。我理解,不是必然死锁,而是释放的几率比较低,估计试验个∞次可能出现一次能够释放。
    至于volatile,文档里这么说:当一个变量被定义为volatile之后,就可以保证此变量对所有线程的可见性,即当一个线程修改了此变量的值的时候,变量新的值对于其他线程来说是可以立即得知的。可以理解成:对volatile变量所有的写操作都能立刻被其他线程得知。
    就是说,一旦主线程修改了这个变量的值,run方法能够及时知道,便于退出。

    2019-07-17 19:08:23
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
Spring Cloud Alibaba - 重新定义 Java Cloud-Native 立即下载
The Reactive Cloud Native Arch 立即下载
JAVA开发手册1.5.0 立即下载