0

我是java中的多线程新手,我不知道如何停止线程。我有一个ArrayList我想停止的线程。这是我的代码片段:

class PrimeThread implements Runnable {
    public void run() {
        while(flag) {
        //do some stuff
        }
    }
    public void cancel() {
        flag = false;
    }
...
}
Class MainClass {
    public static void stopPrimeThreads() {
        for(int i=0; i<primeThreadList.size(); i++) primeThreadList.get(i).cancel();
    }
}

我尝试通过将flag变量设置为来停止线程false。该flag变量是volatile boolean在类本身中声明的。我还尝试使用外部类变量作为哨兵,但这也不起作用。非volatile变量也不能完成这项工作。当我使用不推荐使用的stop()方法时,我得到了我想要的行为,但我不想使用不推荐使用的方法。有人知道如何解决这个问题吗?我错过了一些基本的东西吗?提前致谢。

4

5 回答 5

1

使用你的取消方法不要停在这条线上......

primeThreadList.get(i).stop();

像这样...

primeThreadList.get(i).cancel();
于 2012-12-02T13:34:24.287 回答
1

如果您使用了非易失性字段,JIT 可以优化该字段的读取,即因为您不在线程中修改它。如果您制作该字段volatile,它将确保您的更改始终可见。

于 2012-12-02T13:38:17.893 回答
1

很难知道为什么这不起作用,因为您没有提供 SSCCE,但您应该简单地使用为此设计的中断(),并且即使线程正在等待某个阻塞方法,也允许停止线程:

public void run() {
    while (!Thread.currentThread().isInterrupted()) {
        ...
    }
}

并停止线程:

thread.interrupt();

当然,无论您选择哪种解决方案,如果您在外循环中有另一个长时间运行的循环,线程将不会停止,直到它检查中断/取消标志的值。确保尽可能多地检查标志。

于 2012-12-02T13:40:38.460 回答
1

使内部循环类似于

while (flag) {
   // smaller step 1
   if (!flag) break;
   // so on
}

As a side-note, if your internal loop takes very long time, it may indicate you using some sub-optimal algorithm. Though, if you working with very large numbers, long calculation times are unavoidable.

于 2012-12-02T13:43:48.677 回答
0
class PrimeThread implements Runnable {
    private volatile boolean flag = true;
    public void run() {
        while(flag) {
        //do some stuff
        }
    }
    public void cancel() {
        flag = false;
    }
...
}
Class MainClass {
    public static void stopPrimeThreads() {
        for(int i=0; i<primeThreadList.size(); i++) primeThreadList.get(i).cancel();
    }
}
于 2012-12-02T13:37:03.313 回答