1

我尝试了以下方法,但没有奏效:

“开始”类:

public class Start implements Runnable {

    Start start;
    LoadExample loadExample;
    Thread mainThread;
    Thread loadExampleThread;

    private boolean running = false;
    public static boolean isExampleLoaded = false;

    public static void main(String[] args) {
        begin = new Start();
        loadExample = new LoadExample();
        begin.start();
    }

    public synchronized void start() {
        mainThread = new Thread(this, "Main");
        mainThread.start();
        loadExampleThread = new Thread(loadExample, "Load Example");
        loadExampleThread.start();
    }

    public void run() {
        running = true;
        while (running) {
            if(isExampleLoaded){
                System.out.println("Loaded!");
            }
        }
    }
}

“LoadExample”类:

public class LoadExample implements Runnable {

    public void run(){
        //blabla, loading if you will...
        Start.isExampleLoaded = true;
    }
}

您可能会在上面的代码中发现语法错误,但这仅仅是因为我没有在 Eclipse 中检查就输入了这个。我的原始代码非常相似,Eclipse 没有显示错误或警告。

我的问题是代码不会打印“加载!”。我认为这是因为(1)线程不能更改静态变量或其他类的变量,或者(2)更改仅针对当前线程而不是其他线程更新,但我可能错了。

任何澄清表示赞赏。

编辑:

如果您发现上述任何错误,请告诉我,我会尽快更新。

4

2 回答 2

6

您需要标记变量volatile才能使此示例正常工作。如果没有volatile,读取线程将读取isExampleLoaded一次,而不会再次读取,因为编译器知道该变量尚未写入。

于 2012-08-04T01:37:42.153 回答
1

任何时候你想从多个线程访问一个变量,所有对该变量的访问都应该在一个synchronized块或方法中,都使用同一个监视器。在目前的程序中,如果你制作静态同步isExampleLoaded()setExampleLoaded()方法,并在任何地方使用它们,程序就可以工作。

正如@dasblinkenlight 指出的那样,也可以将变量标记为volatile,这也可以。volatile不能很好地扩展到许多变量或许多线程。在一般情况下,synchronized访问是更好的解决方案。

于 2012-08-04T01:42:31.790 回答