简体   繁体   English

如何杀死在线程中运行的 Runnable?

[英]How do I kill a Runnable running in a Thread?

I have made a class called AbortableThread that is supposed to start and stop a thread when I want to.我制作了一个名为AbortableThread的 class,它应该在我想要的时候启动和停止线程。 The class is relatively small since it just contains this code: class 相对较小,因为它只包含以下代码:

public class AbortableThread implements Runnable
{
    private Thread worker;
    private Runnable target;

    public AbortableThread(Runnable target)
    {
        this.target = target;
    }

    public void start()
    {
        worker = new Thread(this);
        worker.start();
    }

    public void stop()
    {
        worker.interrupt();
    }

    public void run()
    {
        while (!worker.isInterrupted())
            target.run();
    }
}

However, calling stop() does not stop the Thread.但是,调用stop()不会停止线程。 I think that's because target.run() runs on a separate thread, but I have no clue.我认为那是因为target.run()在单独的线程上运行,但我不知道。

There isn't a good way to stop a Runnable from outside (as a last resort there is stop, but that isn't a good way).没有从外部停止 Runnable 的好方法(作为最后的手段,有停止,但这不是一个好方法)。 A Runnable needs to be a good citizen and check for interruption itself, using Thread.currentThread().isInterrupted(). Runnable 需要是一个好公民,并使用 Thread.currentThread().isInterrupted() 检查中断本身。 If the Runnable catches InterruptedException, the interrupt flag will be cleared;如果 Runnable 捕获到 InterruptedException,则中断标志将被清除; the Runnable needs to restore the interrupt flag by calling interrupt on the current thread. Runnable 需要通过在当前线程上调用中断来恢复中断标志。

In the posted code what happens is that the Runnable executes on the worker thread and the worker never gets a chance to check the interruption flag until the Runnable completes.在发布的代码中,发生的情况是 Runnable 在工作线程上执行,并且工作人员在 Runnable 完成之前永远没有机会检查中断标志。 Assuming the Runnable is something like假设 Runnable 类似于

() -> { try {
            Thread.sleep(100000L):
          } catch (InterruptedException e) {}}

then the sleep would be cut short when the worker is interrupted, but the interrupt flag would be cleared so the Runnable would be executed again in the next iteration of the loop.那么当worker被中断时,睡眠将被缩短,但中断标志将被清除,因此Runnable将在循环的下一次迭代中再次执行。

Try something like this:尝试这样的事情:

public class AbortableThread implements Runnable
{
    private final AtomicBoolean running = new AtomicBoolean(false);
    private Thread worker;
    private Runnable target;

    public AbortableThread(Runnable target)
    {
        this.target = target;
    }

    public void start()
    {
        worker = new Thread(this);
        worker.start();
    }

    public void stop()
    {
        running.set(false);
    }

    public void run()
    {
        running.set(true);
        while (running.get()) {
          try { 
            // make an small sleep
            Thread.sleep(1); 
          } catch (InterruptedException e){ 
            Thread.currentThread().interrupt();
            System.out.println(
              "Thread was interrupted, Failed to complete operation");
          }
          // do something here like the one in question; it must be none-blocking
          target.run();
       }
    }
 }

A complete example can be found here:一个完整的例子可以在这里找到:

How to Kill a Java Thread如何杀死 Java 线程

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM