将关闭信号发送到Java中的另一个线程

时间:2013-12-09 00:33:07

标签: java multithreading countdownlatch

我有一个应用程序在一个单独的线程中在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();

}
}

还有其他干净的方法吗?

3 个答案:

答案 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。