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

Java 如何停止通过实现runnable接口创建的线程?,java,multithreading,thread-safety,Java,Multithreading,Thread Safety,我通过实现runnable接口创建了类,然后在我的项目的其他类中创建了许多线程(将近10个)。如何停止其中一些线程?不建议中途停止(杀死)线程。该API实际上已被弃用 但是,您可以在此处获得更多详细信息,包括解决方法:最简单的方法是中断()它,这将导致线程.currentThread().isInterrupted()返回true,并且在线程正在等待的特定情况下也可能抛出中断异常,例如Thread.sleep(),otherThread.join(),object.wait()等 在run()方

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

不建议中途停止(杀死)线程。该API实际上已被弃用

但是,您可以在此处获得更多详细信息,包括解决方法:

最简单的方法是
中断()
它,这将导致
线程.currentThread().isInterrupted()
返回
true
,并且在线程正在等待的特定情况下也可能抛出
中断异常,例如
Thread.sleep()
otherThread.join()
object.wait()

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

注意:尽管
Thread.interrupted()
看起来与
isInterrupted()
相同,但它有一个令人讨厌的副作用:调用
interrupted()
会清除
interrupted
标志,而调用
isInterrupted()
则不会


其他非中断方法包括使用正在运行的线程监视的“停止”(
volatile
)标志。

如果您使用
ThreadPoolExecutor
,并且您使用该方法,它将为您提供一个
未来的
。您可以调用返回的Future来停止
Runnable
任务。

在中途使用
thread.stop()
停止线程不是一个好做法。更合适的方法是以编程方式使线程返回。让可运行对象在
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);
    }
}
如何停止通过实现runnable接口创建的线程

有很多方法可以停止线程,但它们都需要特定的代码来完成。停止线程的典型方法是使用
volatile boolean shutdown
字段,线程每隔一段时间检查该字段:

  // set this to true to stop the thread
  volatile boolean shutdown = false;
  ...
  public void run() {
      while (!shutdown) {
          // continue processing
      }
  }
您还可以中断导致
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;
          }
      }
  }
请注意,使用
interrupt()
中断线程不一定会导致它立即抛出异常。只有当您使用的方法是可中断的,才会抛出
InterruptedException

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

public class MyRunnable implements Runnable {
    private volatile boolean shutdown;
    public void run() {
        while (!shutdown) {
            ...
        }
    }
    public void shutdown() {
        shutdown = true;
    }
}
Thread.currentThread().isInterrupted()工作异常正常。但是这个 代码仅用于暂停计时器。

此代码停止并重置线程计时器。 h1是处理程序名称。 此代码是在按钮单击侦听器中添加的。 w_h=分钟w_m=毫秒i=计数器


在我的类中,我编写了一个将flag设置为false的方法。但我无法从需要停止线程的另一个类访问此方法。假设创建线程的类负责停止线程,则应在此类中维护对可运行实例的引用,并使用此引用,设置标志的方法应该被调用。如果你不介意的话,你可以用一个例子来说明一个例子:你应该让你的<代码>停止>代码>变量。如果我想在代码的中间取消>一些商业逻辑< /代码>,这不会使它运行“整个业务逻辑”吗?因为标志正在while循环的下一次迭代中检查。在我的类中,我编写了一个方法,将标志(在您的示例中为shutdown)设置为true。但是我无法从需要停止线程的另一个类访问此方法。是的,您需要以某种方式公开它。我通常执行类似于
公共类MyClass实现可运行的{volatile boolean shutdown;public void run(){if(!shutdown){…}}}
。您可以添加设置关闭标志的
shutdown()
方法。然后执行
新线程(new MyClass()).start()
来运行它。我的线程中没有
while
,但有时我仍然需要在它处理
run
方法中的所有行之前停止它,然后您可以使用
if
@user25。如果您需要更多帮助,我会花时间问一个完整的问题。cancel尝试取消执行,但不能保证执行。我的线程中没有
while
,但有时我仍然需要在它处理
run
方法中的所有行之前停止它
 i=0;
            w_h = 0;
            w_m = 0;


            textView.setText(String.format("%02d", w_h) + ":" + String.format("%02d", w_m));
                        hl.removeCallbacksAndMessages(null);
                        Thread.currentThread().isInterrupted();


                        }


                    });


                }`