while循环和线程的无限循环问题

Son*_*man 5 java multithreading infinite-loop while-loop

使用一个基本的例子来说明我的问题,我有2个几乎相同的代码位.

此代码使while循环无限运行.

private boolean loadAsset() {
    new Thread(new Runnable() {

        @Override
        public void run() {

            // Do something
            loaded = true;

        }
    }).start();

    while (!loaded) {
        // System.out.println("Not Loaded");
    }
    System.out.println("Loaded");
    return false;
}
Run Code Online (Sandbox Code Playgroud)

然而,这段代码(即在while循环中执行某些操作)会导致loaded变量被成功评估,并允许while循环中断和方法完成.

private boolean loadAsset() {
    new Thread(new Runnable() {

        @Override
        public void run() {

            // Do something
            loaded = true;

        }
    }).start();

    while (!loaded) {
        System.out.println("Not Loaded");
    }
    System.out.println("Loaded");
    return false;
}
Run Code Online (Sandbox Code Playgroud)

任何人都可以向我解释为什么会这样吗?

Luk*_*der 7

第一个循环仅"出现"无限运行.您实际上正在运行"活动等待",烧掉100%的CPU,这样您的操作系统或JVM就无法进行上下文切换并让另一个线程运行.

随着System.out.println()在另一方面,有I/O参与,造成了一定程度上"无效的等待".操作系统或JVM可以切换上下文,另一个线程启动.

如果你运行你的第一个程序10个小时,我肯定循环最终会破坏


Nei*_*fey 6

检查'loaded'是否明确声明为volatile.

说明:如果多个线程读取和/或写入变量,则需要采取适当的线程安全措施.一种这样的线程安全措施是易失性的,它适用于原始值(或对象引用),它们被读取或写为"简单"动作,其值在给定的情况下写入而不依赖于先前读取的值.有关更多信息,我在我的网站上有一篇关于volatile的文章(以及有关线程安全的其他信息)可能会有所帮助.