使用中断Java Runnable和运行清理的首选方法是什么?

使用中断Java Runnable和运行清理的首选方法是什么?,java,multithreading,concurrency,interrupt,Java,Multithreading,Concurrency,Interrupt,关于设计的一般问题。我有几个线程需要在后台运行,基本上是一些数据库上传/故障处理任务。这些都具有以下流动模式: public class Worker implements Runnable { private AtomicBoolean isAlive = new AtomicBoolean(true); .... public void run() { while (isAlive.get()) { // do some wo

关于设计的一般问题。我有几个线程需要在后台运行,基本上是一些数据库上传/故障处理任务。这些都具有以下流动模式:

public class Worker implements Runnable {
    private AtomicBoolean isAlive = new AtomicBoolean(true);
    ....
    public void run() {
        while (isAlive.get()) {

            // do some work here, slightly heavy

            if (Thread.interrupted()) {
                // checking Thread.interrupted() as the code above
                // can take a while and interrupt may happen before 
                // it gets here.
                isAlive.setBoolean(false);
                break; // to exit faster
            }

            try { Thread.sleep(sleepTime); } 
            catch (InterruptedException e) {
                isAlive.setBoolean(false);
                break; // to exit faster
            }
        }

        cleanUp(); // e.g. close db connections etc
     }
}
现在我希望能够中断线程,这样它就可以优雅地跳出while循环并运行
cleanUp()
方法

有很多方法可以做到这一点,下面列出一些:

  • 线程中的
    可运行程序
    踢出,然后使用
    中断()
    方法:

    List<Thread> threadList =...
    for (int i < 0; i < threadCount; i++) {
        Thread t = new Thread(new Worker());
        threadList.add(t);
        t.start()
    }
    
    // later
    for (Thread t : threadList) { t.interrupt(); }
    

  • 处理这种工作流的方法是什么?为什么?欢迎所有想法。

    总之,我个人认为将
    isAlive
    设置为
    false
    是最干净的。 据我所知,
    interrupt()
    是本机代码,这本身就是远离它的原因


    别忘了将
    布尔值设置为
    volatile

    我认为这两种方法都是可以接受的。如果你有很多线程,我会选择线程池方法,以便于管理。如果你只有一个(也许两个)线程,我会分别中断它们

    正如MouseEvent所说,不使用中断并使用isAlive变量(在您的实现中似乎毫无意义)会更干净。但是,这意味着您需要关闭或关闭每个实例(这仍然是一个好方法)


    另外,我将在try-catch-finally语句中围绕整个方法,在其中捕获中断并在finally子句中进行清理。

    编辑并添加代码以更改isAlive,我将中断循环,使其更快退出。最后试着抓住——好主意。实际上,在try子句中添加更多代码/更慢的代码会对性能造成影响吗?不。。。除非抛出异常,否则不会造成性能损失。此外,isAlive检查正好在中断检查之前。我想两个人会同时把你踢出去。如果有任何性能提升,它将远小于一毫秒。添加了一些关于我为什么使用
    Thread.interrupted()
    的注释,稍微更改了代码以反映我的意思。谢谢,谢谢。实际上我更喜欢使用原子布尔。更改代码以反映这一点。在某些情况下,volatile可能会影响性能,特别是对于频繁访问。一般来说,volatile是一种更便宜的方法。原子变量只是有多一点灵活性。。。不要担心这么小的性能影响。它将缩短您的时间,并且对整个应用程序的影响可以忽略不计。您需要担心的是I/O操作和TCP连接。这是真的,在本例中无关紧要
    记住当与
    static
    一起使用时,
    volatile
    会成为一个问题,并且有很多线程访问它。
    cleanUp()
    应该位于
    finally
    块中,除非您希望在发生意外异常时保持数据库连接打开。
    ThreadPoolExecutor executor = new ....;
    executor.execute(new Worker()); 
    
    // some lines else later
    executor.shutdownNow();  // shutdown() doesn't interrupt?