如何停止通过实现runnable接口创建的线程?

svk*_*nky 55 java multithreading thread-safety

我通过实现runnable接口创建了类,然后在我的项目的其他一些类中创建了许多线程(将近10个).
如何阻止其中一些线程?

Boh*_*ian 76

最简单的办法就是interrupt()它,这将导致Thread.currentThread().isInterrupted()返回true,也可能抛出InterruptedException在某些情况下,其中线程等待,例如Thread.sleep(),otherThread.join(),object.wait()等.

run()方法内部,您需要捕获该异常和/或定期检查Thread.currentThread().isInterrupted()值并执行某些操作(例如,突破).

注意:虽然Thread.interrupted()看起来一样isInterrupted(),它有一个讨厌的副作用:呼叫interrupted() 清除interrupted标志,而调用isInterrupted()没有.

其他非中断方法涉及使用volatile正在运行的Thread监视的"stop"()标志.


Gra*_*ray 35

如何停止通过实现runnable接口创建的线程?

有很多方法可以阻止一个线程,但是所有这些方法都需要特定的代码来执行此操作.停止线程的典型方法是让volatile boolean shutdown线程经常检查一个字段:

  // set this to true to stop the thread
  volatile boolean shutdown = false;
  ...
  public void run() {
      while (!shutdown) {
          // continue processing
      }
  }
Run Code Online (Sandbox Code Playgroud)

您也可以中断导致线程sleep(),wait()以及其他一些方法抛出InterruptedException.您还应该测试线程中断标志,例如:

  public void run() {
      while (!Thread.currentThread().isInterrupted()) {
          // continue processing
          try {
              Thread.sleep(1000);
          } catch (InterruptedException e) {
              // good practice
              Thread.currentThread().interrupt();
              return;
          }
      }
  }
Run Code Online (Sandbox Code Playgroud)

请注意,中断线程与interrupt()不会必然导致其立即抛出异常.只有当你处于可中断的方法中时才会InterruptedException抛出.

如果要向shutdown()实现的类添加方法Runnable,则应定义自己的类,如:

public class MyRunnable implements Runnable {
    private volatile boolean shutdown;
    public void run() {
        while (!shutdown) {
            ...
        }
    }
    public void shutdown() {
        shutdown = true;
    }
}
Run Code Online (Sandbox Code Playgroud)


San*_*osh 10

在中途停止线程不是一个好习惯.更合适的方法是使线程以编程方式返回.让Runnable对象在run()方法中使用共享变量.每当您希望线程停止时,请将该变量用作标志.

编辑:示例代码

class MyThread implements Runnable{

    private Boolean stop = false;

    public void run(){

        while(!stop){

            //some business logic
        }
    }
    public Boolean getStop() {
        return stop;
    }

    public void setStop(Boolean stop) {
        this.stop = stop;
    }       
}

public class TestStop {

    public static void main(String[] args){

        MyThread myThread = new MyThread();
        Thread th = new Thread(myThread);
        th.start();

        //Some logic goes there to decide whether to 
        //stop the thread or not. 

        //This will compell the thread to stop
        myThread.setStop(true);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 你应该使你的`stop`变量变得不稳定. (6认同)
  • 如果我想在“某些业务逻辑”中间取消怎么办,这不会让它运行“整个业务逻辑”吗?因为在 while 循环的下一次迭代时将检查该标志。 (2认同)

Kul*_*ain 6

如果您使用ThreadPoolExecutor,并使用submit()方法,它将Future返回给您.您可以在返回的Future上调用cancel()来停止您的Runnable任务.

  • 取消尝试取消执行但不保证. (2认同)