使用sentinel停止线程不起作用

时间:2012-12-02 13:32:08

标签: java multithreading arraylist sentinel

我是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()方法时,我得到了我想要的行为,但我不想使用弃用的方法。 有没有人知道如何解决这个问题?我错过了什么基本的东西? 提前谢谢。

5 个答案:

答案 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();
    }
}