我是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()
方法时,我得到了我想要的行为,但我不想使用弃用的方法。
有没有人知道如何解决这个问题?我错过了什么基本的东西?
提前谢谢。
答案 0 :(得分:1)
使用您的取消方法,不要在此行停止...
primeThreadList.get(i).stop();
像这样......
primeThreadList.get(i).cancel();
答案 1 :(得分:1)
如果您使用了非易失性字段,JIT可以优化该字段的读取,即因为您不在线程中修改它。如果您创建字段volatile
,它将确保您始终可以看到更改。
答案 2 :(得分:1)
很难知道为什么这不起作用,因为你没有提供SSCCE,但你应该只使用为此设计的interrupt(),并允许停止线程,即使它正在等待一些阻塞方法:
public void run() {
while (!Thread.currentThread().isInterrupted()) {
...
}
}
并停止线程:
thread.interrupt();
当然,无论你选择什么解决方案,如果你在外部循环中有另一个长时间运行的循环,线程将不会停止,直到它检查中断/取消标志的值。务必尽可能经常检查标志。
答案 3 :(得分:1)
使内部循环类似于
while (flag) {
// smaller step 1
if (!flag) break;
// so on
}
作为旁注,如果内部循环需要很长时间,可能表示您使用了一些次优算法。但是,如果使用非常大的数字,则计算时间长是不可避免的。
答案 4 :(得分: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();
}
}