我有一个应用程序在一个单独的线程中在while循环中重复运行某些东西,直到用户触发关闭信号。我可以通过在工作线程中设置(volatile)布尔字段将信号从主线程发送到工作线程,但是有没有其他方法可以关闭/中断线程,例如通过'java.util.concurrent'中的任何实用程序?
我试过调用ExecutorService的shutdown()或shutdownNow()方法,但是它们无法停止工作线程。同时在建议here的while条件下调用shutdown()并使用!Thread.currentThread().isInterrupted()
也无法打破循环。我能找到的另一种方法是使用CountDownLatch,但是在这里我必须在while循环的条件中使用CountDownLatch.getCount() != 0
,但是这个方法的javadoc文档说
此方法通常用于调试和测试目的。
这使得IMO成为一个值得怀疑的方法。以下是我的示例代码
class Worker implements Runnable {
//private volatile boolean shutdown = false; --> alternative to countdownlatch
@Override
public void run() {
while (countDownLatch.getCount() != 0) {
//do some work
}
}
}
public class App {
public static void main(String[] args) {
System.out.println("Press enter to stop");
CountDownLatch countDownLatch = new CountDownLatch(1);
ExecutorService es = Executors.newFixedThreadPool(1);
es.execute(new Worker(countDownLatch));
Scanner scanner = new Scanner(System.in);
scanner.nextLine();
System.out.println("Shut down signal received");
countDownLatch.countDown(); //an alternative would be to set a boolean variable in worker
es.shutdownNow();
}
}
还有其他干净的方法吗?
答案 0 :(得分:2)
还有其他干净的方法吗? 不。坚持使用( volatile )布尔值。
我确定Thread.stop()会起作用,但是没有机会正确清理。使用interrupted()/ isInterrupted()会起作用,但它比布尔值复杂一点。另外,有些时候你不想因为中断而退出循环。我有几个地方的代码,我从InterruptedException(或类似的东西)恢复,然后检查我的布尔(或其他),并根据其值,继续或不。
布尔值与其他人一起玩得很好。我已经提到了中断。你可能有一天会有20个不同的理由在10个(或更多)的任何一个地方停止循环。那个布尔符合适合;你可以轻松地编写代码,这样你的线程总是在布尔值为真时停止,或者从不在它错误时停止,或者你需要做的其他事情。
答案 1 :(得分:1)
你必须检查循环中的Thread.interrupted(),以便用System.exit()之外的东西将其关闭。然后你可以使用thread.interrupt(),这是ExecutorService.shutdown()所使用的。如果它不起作用,请向我们展示您检查isInterrupted()的代码,以便我们可以修复它。 Thread.stop()存在,但有充分理由弃用,不应使用。
答案 2 :(得分:0)
您可以从[Executors] [http://docs.oracle]获取[ExecutorService] [http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html] .com / javase / 7 / docs / api / java / util / concurrent / Executors.html]
通过引用主线程中的ExecutorsService,您可以在收到信号时关闭ThreadPool。