在下面的代码中,我有一个while(true)循环。 考虑到try块中存在一些代码的情况,其中线程应该执行一些约需一分钟的任务,但是由于某些预期的问题,它正在运行。我们可以阻止那个线程吗?
public class thread1 implements Runnable {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
thread1 t1 = new thread1();
t1.run();
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
try{
Thread.sleep(10);
}
catch(Exception e){
e.printStackTrace();
}
}
}
}
答案 0 :(得分:42)
首先,你没有在这里开始任何线程!您应该创建一个新线程并将名为thread1
Runnable
的名称thread1 t1 = new thread1();
final Thread thread = new Thread(t1);
thread.start();
传递给它:
interrupt()
现在,当你真的有一个线程时,有一个内置的功能来中断正在运行的线程,称为...... thread.interrupt();
:
while(!Thread.currentThread().isInterrupted()){
try{
Thread.sleep(10);
}
catch(InterruptedException e){
Thread.currentThread().interrupt();
break; //optional, since the while loop conditional should detect the interrupted state
}
catch(Exception e){
e.printStackTrace();
}
但是,单独设置此标志不会执行任何操作,您必须在正在运行的线程中处理此问题:
while
有两点需要注意:isInterrupted()
循环现在将在线程InterruptedException
结束。但是如果线程在睡眠期间被中断,那么JVM非常友好,它会通过sleep()
抛出AtomicBoolean
来通知你。抓住它并打破你的循环。就是这样!
至于其他建议:
<强>已过时即可。这种方法本质上是不安全的[...]
volatile
或sleep
!),但为什么JDK已经为您提供了这样的内置标志呢?额外的好处是中断{{1}},使线程中断更具响应性。 答案 1 :(得分:5)
停止线程的正确方法是interrupt
它(stop()
已被弃用,可能会产生令人讨厌的副作用):
t1.interrupt()
这会导致InterruptedException
或Thread.sleep()
等方法引发Object.wait()
。
然后只需为此异常添加一个catch块,只需break
循环while
。
run()
ning Runnable
。您需要在某个时刻调用Thread.start()
来生成新线程。
答案 2 :(得分:2)
在开始执行线程之前创建一个您设置为boolean keepGoing
的字段true
,并将while (true)
替换为while (keepGoing)
。在某些时候,您决定在哪里,只需将keepGoing
的值更改为false
,它就会退出循环。
答案 3 :(得分:2)
停止任意线程的唯一方法是中断。保持对它的引用然后调用中断方法。
答案 4 :(得分:2)
将catch中断移到循环外部。这不需要任何代码行,它只是正确处理中断,即操作被中断。
public void run() {
try{
while(true) {
Thread.sleep(10);
}
} catch(InterruptedException e){
System.out.println("Thread interrupted"));
}
}
答案 5 :(得分:1)
我建议使用Thread.interrupt()
(如@Bohemian所述)。与使用 ad-hoc 标志相比,它有几个优点:
您无需创建和使用特定于应用程序的API来执行此操作。 (中断可以保证线程安全......)
Thread.interrupt()
将中断在wait()
或join
中阻塞的线程,或者可能 1 阻塞I / O调用的线程。< / p>
但是,它不是一个神奇的子弹。如果您尝试停止的线程正在执行常规代码,则需要定期检查其interrupted()
标志,否则不会停止。这使我们像使用 ad-hoc 标志机制一样处于船上。线程必须合作,否则无法(安全地)停止。
1 - 这是一个阴暗的地方。一方面,有一个InterruptedIOException
,其javadoc说“表明I / O操作已被中断”。另一方面,javadoc中没有为各种java.io
流类明确提到异常。
确实有些第三方代码可能无法正确处理interrupted
标志,因此中断可能会被“吃掉”。但是如果你有源代码,你可以检查一下。对于没有关注 ad-hoc 标志机制的第三方代码,情况并没有太大的不同。
我不建议使用Thread.stop()
。它从根本上说是好消息。有些人声称这对他们有用,但IMO要么处理一个有效的特殊情况......要么他们很幸运。