Java 如何停止一个永远运行而没有任何用处的线程
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6410721/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to stop a thread that is running forever without any use
提问by randeepsp
In the below code, i have a while(true) loop. considering a situation where there is some code in the try block where the thread is supposed to perform some tasks which takes about a minute, but due to some expected problem, it is running for ever. can we stop that thread ?
在下面的代码中,我有一个 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();
}
}
}
}
采纳答案by Tomasz Nurkiewicz
First of all, you are not starting any thread here! You should create a new thread and pass your confusingly named thread1
Runnable
to it:
首先,你不是在这里开始任何线程!您应该创建一个新线程并将您令人困惑的名称传递thread1
Runnable
给它:
thread1 t1 = new thread1();
final Thread thread = new Thread(t1);
thread.start();
Now, when you really have a thread, there is a built in feature to interrupt running threads, called... interrupt()
:
现在,当您真的有一个线程时,有一个内置功能可以中断正在运行的线程,称为... interrupt()
:
thread.interrupt();
However, setting this flag alone does nothing, you have to handle this in your running thread:
但是,单独设置此标志没有任何作用,您必须在正在运行的线程中处理此问题:
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();
}
Two things to note: while
loop will now end when thread isInterrupted()
. But if the thread is interrupted during sleep, JVM is so kind it will inform you about by throwing InterruptedException
out of sleep()
. Catch it and break your loop. That's it!
需要注意的两件事:while
loop 现在将在 thread 时结束isInterrupted()
。但是,如果线程睡眠期间中断,JVM是那么亲切它会通知你抛出InterruptedException
的出来sleep()
。抓住它并打破你的循环。就是这样!
As for other suggestions:
至于其他建议:
- About Thread.stop():
Deprecated. This method is inherently unsafe[...]
已弃用。这种方法本质上是不安全的[...]
- Adding your own flag and keeping an eye on it is fine (just remember to use
AtomicBoolean
orvolatile
!), but why bother if JDK already provides you a built-in flag like this? The added benefit is interruptingsleep
s, making thread interruption more responsive.
- 添加您自己的标志并密切关注它很好(只需记住使用
AtomicBoolean
或volatile
!),但是如果 JDK 已经为您提供了这样的内置标志,为什么还要麻烦呢?额外的好处是中断sleep
s,使线程中断响应更快。
回答by SteeveDroz
Create a field boolean keepGoing
that you set to true
before starting your thread and replace while (true)
with while (keepGoing)
. At some point, you decide where, simply change the value of keepGoing
to false
and it will exit the loop.
创建一个boolean keepGoing
您true
在开始线程之前设置的字段并替换while (true)
为while (keepGoing)
. 在某些时候,您决定在哪里,只需更改keepGoing
to的值,false
它就会退出循环。
回答by Costi Ciudatu
The proper way to stop a thread is to interrupt
it (stop()
is deprecated and may have nasty side effects):
停止线程的正确方法是interrupt
它(stop()
已弃用,可能会产生令人讨厌的副作用):
t1.interrupt()
This will cause an InterruptedException
to be thrown by methods like Thread.sleep()
or Object.wait()
.
这将导致 anInterruptedException
被像Thread.sleep()
or 之类的方法抛出Object.wait()
。
Then just add a catch block for this exception and simply break
out of the while
loop.
然后只需为此异常添加一个 catch 块并简单地break
退出while
循环。
EDIT: I now realised that your infinite loop is running within the main thread, there's no thread created by your code, it's just run()
ning a Runnable
. You need to call Thread.start()
at some point to spawn a new thread.
编辑:我现在意识到,你的无限循环的主线程中运行,有没有您的代码创建的线程,它只是run()
宁一Runnable
。您需要Thread.start()
在某个时候调用以生成一个新线程。
回答by Bohemian
The onlyway to stop an arbitrary thread is by interruptingit. Keep a reference to it then call the interrupt method.
停止任意线程的唯一方法是中断它。保持对它的引用,然后调用中断方法。
回答by Stephen C
I recommend using Thread.interrupt()
(as mentioned by @Bohemian). It has a couple of advantages over using ad-hocflags:
我建议使用Thread.interrupt()
(如@Bohemian 所述)。与使用ad-hoc标志相比,它有几个优点:
You don't need to create and use an application-specific API to do this. (And interrupts are guaranteed thread-safe ...)
Thread.interrupt()
will interrupt threads that are blocked in await()
or ajoin
, or possibly1some blocking I/O calls.
您不需要创建和使用特定于应用程序的 API 来执行此操作。(并且中断保证线程安全......)
Thread.interrupt()
将中断在 await()
或 a中阻塞的线程join
,或者可能是1一些阻塞 I/O 调用。
However, it is not a magic bullet. If the thread you are trying to stop is executing regular code, it needs to periodically check its interrupted()
flag, or it won't no to stop. This leaves us in the same as boat as we are in with an ad-hocflag mechanism. The thread has to cooperate, or it can't be (safely) stopped.
然而,它不是灵丹妙药。如果您试图停止的线程正在执行常规代码,则它需要定期检查其interrupted()
标志,否则它不会停止。这让我们和船一样,因为我们使用了一个特别的标志机制。线程必须协作,否则无法(安全)停止。
1 - This is a murky area. On the one hand, there is an InterruptedIOException
whose javadoc says "Signals that an I/O operation has been interrupted". On the other hand, the exception is not explicitly mentioned in the javadocs for the various java.io
stream classes.
1 - 这是一个模糊的区域。一方面,有一个InterruptedIOException
他的 javadoc 说“I/O 操作已被中断的信号”。另一方面,在各种java.io
流类的 javadocs 中没有明确提到异常。
It is true that some 3rd-party code may not deal with the interrupted
flag properly, and interrupts may get "eaten" as a result. But you can check for that if you have source code. And the situation is not a lot different to the 3rd-party code not paying attention to your ad-hocflag mechanism.
确实,某些第 3 方代码可能无法interrupted
正确处理标志,因此可能会“吃掉”中断。但是如果你有源代码,你可以检查一下。这种情况与不注意您的临时标志机制的第 3 方代码没有太大不同。
I would NOTrecommend using Thread.stop()
. It is fundamentally flakey. Some people claim that it works for them, but IMO they are either dealing with a special case that works ... or they are being lucky.
我不建议使用Thread.stop()
. 它从根本上说是片状的。有些人声称它对他们有用,但 IMO 他们要么正在处理一种有效的特殊情况……要么他们很幸运。
回答by Peter Lawrey
Move the catch interrupt to outside the loop. This doesn't require any more lines of code, it just handles interrupts correctly i.e. the action is interrupted.
将捕获中断移到循环外。这不需要更多的代码行,它只是正确处理中断,即操作被中断。
public void run() {
try{
while(true) {
Thread.sleep(10);
}
} catch(InterruptedException e){
System.out.println("Thread interrupted"));
}
}