当有多个线程时,跳出循环的最佳方法是什么?

时间:2013-12-12 13:46:39

标签: java multithreading thread-safety semaphore

我有一个游戏循环的方法:

boolean playing = true; 
while(playing) {} 

在该循环中,大约有10个方法被调用。

循环在Thread的run()方法中,一次运行大约20个线程。

线程会将彼此的播放变量更改为false。

所以:

while (playing) {
   doSomething1();
   doSomething2();
   doSomething3();
   doSomething4();
   doSomething5();
   etc();

}

无需添加,无处不在;

 if (playing) doSomething1(); 

 if (!playing) break;

并且在线程上没有调用中断的情况下,如何在从true变为false的情况下使运行结束?

我确实需要在播放更改时让循环的内容直接运行到行,所以只使用像synchronized这样的东西将无效。

或许它会,我只是不知道它。

2 个答案:

答案 0 :(得分:1)

除了你这样做之外别无他法。只需在执行流程中的适当时刻检查一下。

如果您认为其他任何事情都是危险的 - 只有您的线程知道什么时候可以安全停止,否则它可能会在修改某些内容的一半时间终止并让更改完成一半。

你可以做的一件事就是避免重复的代码:

public Interface ThreadTask {
    void run();
}

ThreadTask[] tasks;

while (playing) {
   for (ThreadTask tt: tasks) {
       if (!playing) {
           break;
       }
       tt.run();
   }
}

总的来说,虽然我不希望你执行一个游戏循环需要这么长时间,以至于每次在循环周围检查多次播放都是一个问题。否则,无论如何你都需要打破那些长期运行的任务,以保持响应。

答案 1 :(得分:0)

将您的某些事项列表重构为enum

enum Things {

    Something1 {
                @Override
                void doIt() {

                }
            },
    Something2 {
                @Override
                void doIt() {

                }
            },
    Something3 {
                @Override
                void doIt() {

                }
            };

    abstract void doIt();
}

volatile boolean playing = true;

public void play() {
    while (playing) {
        for (Things it : Things.values()) {
            if (playing) {
                it.doIt();
            } else {
                break;
            }
        }
    }
}

例如,当您决定在所有其他Something2之间拨打Something时,此技巧还会打开您未来的播放循环。