如何停止通过实现可运行接口创建的线程?
Posted
技术标签:
【中文标题】如何停止通过实现可运行接口创建的线程?【英文标题】:How to stop a thread created by implementing runnable interface? 【发布时间】:2012-05-24 17:39:27 【问题描述】:我通过实现可运行接口创建了类,然后在我的项目的其他一些类中创建了许多线程(近 10 个)。如何停止其中一些线程?
【问题讨论】:
【参考方案1】:最简单的方式是interrupt()
它,这将导致Thread.currentThread().isInterrupted()
返回true
,并且在线程为的某些情况下还可能抛出InterruptedException
等待,例如Thread.sleep()
、otherThread.join()
、object.wait()
等
在 run()
方法中,您需要捕获该异常和/或定期检查 Thread.currentThread().isInterrupted()
值并执行某些操作(例如,突破)。
注意:虽然Thread.interrupted()
看起来与isInterrupted()
相同,但它有一个讨厌的副作用:调用interrupted()
清除 interrupted
标志,而调用isInterrupted()
则不会。
其他非中断方法涉及使用正在运行的线程监控的“停止”(volatile
) 标志。
【讨论】:
我的线程中没有while
,但有时我仍然需要在它处理run
方法中的所有行之前停止它【参考方案2】:
如何停止通过实现可运行接口创建的线程?
有很多方法可以停止线程,但它们都需要特定的代码来完成。停止线程的典型方法是设置一个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
才会被抛出。
如果您想在实现Runnable
的类中添加shutdown()
方法,您应该定义自己的类,例如:
public class MyRunnable implements Runnable
private volatile boolean shutdown;
public void run()
while (!shutdown)
...
public void shutdown()
shutdown = true;
【讨论】:
在我的班级中,我编写了一个将标志(在您的示例中为关闭)设置为 true 的方法。但我无法从需要停止线程的其他班级访问此方法。跨度> 是的,您需要以某种方式公开它。我通常会做类似public class MyClass implements Runnable volatile boolean shutdown; public void run() if (! shutdown) ...
的事情。您可以添加一个设置关闭标志的shutdown()
方法。然后你会做new Thread(new MyClass()).start();
来运行它。
我的线程中没有while
,但有时我仍然需要在它处理run
方法中的所有行之前停止它
然后你可以使用if
@user25。如果您需要更多帮助,我会花时间问一个完整的问题。【参考方案3】:
停止使用Thread.stop()
中途的线程不是一个好习惯。更合适的方法是让线程以编程方式返回。让 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);
【讨论】:
在我的班级中,我编写了一个将标志设置为 false 的方法。但我无法从需要停止线程的其他班级访问此方法。 假设创建线程的类负责停止它,则应在此类中维护对 Runnable 实例的引用,并使用此引用调用设置标志的方法。 如果你不介意,你可以举个例子更清楚一点 你应该让你的stop
变量可变。
如果我想在 some bussiness logic
中间取消怎么办,这不会让它运行“整个业务逻辑”吗?因为在 while 循环的下一次迭代中正在检查标志。【参考方案4】:
如果你使用ThreadPoolExecutor
,并且你使用submit()方法,它会给你一个Future
。您可以在返回的 Future 上调用 cancel() 来停止您的 Runnable
任务。
【讨论】:
cancel 尝试取消执行,但不保证。【参考方案5】:不建议在中途停止(杀死)线程。 API 实际上已被弃用。
但是,您可以在此处获取更多详细信息,包括解决方法:How do you kill a thread in Java?
【讨论】:
【参考方案6】:Thread.currentThread().isInterrupted() 运行良好。但是这个 代码只是暂停计时器。
此代码是停止并重置线程计时器。 h1 是处理程序名称。 此代码添加在您的按钮单击侦听器中。 w_h =分钟 w_m =毫秒 i=计数器
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();
);
`
【讨论】:
以上是关于如何停止通过实现可运行接口创建的线程?的主要内容,如果未能解决你的问题,请参考以下文章