java 如何中断无限循环
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12002450/
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 interrupt an Infinite Loop
提问by big zero
Though I know it'll be a bit silly to ask, still I want to inquire more about the technical perspective of it.
虽然我知道这样问会有点傻,但我还是想更多地了解它的技术角度。
A simple example of an infinite loop:
一个无限循环的简单例子:
public class LoopInfinite {
public static void main(String[] args) {
for (;;) {
System.out.println("Stack Overflow");
}
}
}
How can I interrupt (stop) this infinite loop from outside of this class (e.g., with the help of inheritance)?
我怎样才能从这个类的外部中断(停止)这个无限循环(例如,在继承的帮助下)?
回答by David Grant
I feel dirty even writing this, but...
我什至觉得写这个很脏,但是......
From a different thread, you could call System.setOut()
with a PrintStream
implementation, which throws a RuntimeException
when you call println()
.
从不同的线程,您可以调用System.setOut()
一个PrintStream
实现,RuntimeException
当您调用println()
.
回答by Subhrajyoti Majumder
We can achieve it using volatile
variable, which we will change ouside Thread
and stop the loop.
我们可以使用volatile
变量来实现它,我们将改变它Thread
并停止循环。
for(;!cancelled;) /*or while(!cancelled)*/{
System.out.println("Stackoverflow");
}
This is better way to write Infinite Loop.
这是编写无限循环的更好方法。
public class LoopInfinite{
private static volatile boolean cancelled=false;
public static void main(String[] args){
for(;!cancelled;) { //or while(!cancelled)
System.out.println("Stackoverflow");
}
}
public void cancel(){
cancelled=true;
}
}
回答by Joel Westberg
You canget at the thread running the infinite loop from a different thread and call interrupt on it. You'll have to be very sure what you are doing though, and hope that the interrupted thread will behave properly when interrupted.
您可以从不同的线程获取运行无限循环的线程并对其调用中断。不过,您必须非常确定自己在做什么,并希望被中断的线程在被中断时能够正常运行。
Here, I've named the thread with the offending loop for easier identification. Beware that the following solution is vulnerable to race conditions.
在这里,为了更容易识别,我用有问题的循环命名了线程。请注意,以下解决方案容易受到竞争条件的影响。
Thread loop = new Thread() {
public void run() {
Thread.currentThread().setName("loop");
while(true) {
System.out.print(".");
}
}
}.start();
Then in some other class:
然后在其他一些班级:
ThreadGroup group = Thread.currentThread().getThreadGroup();
Thread[] threads = new Thread[group.activeCount()];
group.enumerate(threads);
for(Thread t : threads) {
if(t.getName().equals("loop")) {
/* Thread.stop() is a horrible thing to use.
Use Thread.interrupt() instead if you have
any control over the running thread */
t.stop();
}
}
Note that in my example I assume the two threads are in the same ThreadGroup. There is no guarantee that this will be the case, so you might need to traverse more groups.
请注意,在我的示例中,我假设两个线程在同一个 ThreadGroup 中。无法保证一定会出现这种情况,因此您可能需要遍历更多组。
If you have some control over this, a decent pattern here would be to have while(!isInterrupted())
instead in the loop declaration and use t.interrupt()
instead of t.stop()
.
如果您对此有一定的控制权,那么这里一个不错的模式是while(!isInterrupted())
在循环声明中t.interrupt()
改为使用而不是t.stop()
.
My only advice to you, even after posting this, is to not do this. You cando it, but you really shouldn't.
我对您的唯一建议,即使在发布此信息后,也不要这样做。你可以做到,但你真的不应该。
回答by Dmytro Uhnichenko
I think this is not possible. Only using breakwithin the loop. You could use
我认为这是不可能的。仅在循环内使用break。你可以用
while(cond) {}
And from some other place make it false
从其他地方让它成为假的
回答by Siddharth Tyagi
You can interrupt this thread by keeping its static reference of inherited reference to this Thread [main] by asking from Thread.currentThread(), like this
您可以通过从 Thread.currentThread() 中询问来保持其对这个线程 [main] 的继承引用的静态引用来中断这个线程,就像这样
public class LoopInfinite{
public static Thread main = null;
public static void main(String[] args){
main = Thread.currentThread();
for(;;)
System.out.println("Stackoverflow");
}
}
And to terminate you can call this from some other thread
并终止您可以从其他线程调用它
LoopInfinite.main.interrupt();
But it will only work if both threads are part of the same group. Otherwise calling thread will get SecurityException
但只有当两个线程都属于同一组时它才会起作用。否则调用线程会得到SecurityException
回答by Benj
If you need an "infinite" loop, you sure need a thread (else your app will be stuck until the end of the loop).
如果你需要一个“无限”循环,你肯定需要一个线程(否则你的应用程序将卡在循环结束之前)。
class BigLoop extends Thread
{
private boolean _sexyAndAlive = true;
// make some constructor !
public void softTerminate()
{
_sexyAndAlive = false;
}
public void run()
{
try
{
while( _sexyAndAlive )
{
// Put your code here
}
}
catch( Some Exceptions ... )
{
// ...
}
// put some ending code here if needed
}
}
// in another file :
BigLoop worker = new BigLoop();
worker.start(); // starts the thread
// when you want to stop it softly
worker.softTerminate();
So, this is a simple method to have background running loop.
所以,这是一个让后台运行循环的简单方法。
回答by Thorbear
Very open question, but stopping such loop would most likely require you to operate from another thread. The other thread would then need to set some variable that your infinite loop can check regularly, and if the variable has a certain value; break out of the loop.
非常开放的问题,但停止这样的循环很可能需要您从另一个线程进行操作。然后另一个线程需要设置一些变量,您的无限循环可以定期检查该变量是否具有特定值;跳出循环。
回答by Thor84no
You won't be able to interrupt this particular loop without halting the process entirely. In general, if you're trying to do it from an external source (I'm assuming you have no control over the source code, because if you did you could easily set a condition in the loop, such as a boolean you could set from an external Thread), you will have to halt the running Thread, whether you do this through the Thread object(you'll have to find a reference to it somehow, for example by looping through existing Threads), or whether you halt it as a system process.
如果不完全停止该过程,您将无法中断此特定循环。一般来说,如果您尝试从外部来源执行此操作(我假设您无法控制源代码,因为如果您这样做了,您可以轻松地在循环中设置条件,例如您可以设置的布尔值从外部线程),您将不得不停止正在运行的线程,无论您是通过Thread 对象执行此操作(您必须以某种方式找到对它的引用,例如通过循环现有 Threads),还是您是否停止它作为一个系统进程。
Another option would be to override the method with a loop that isn't an infinite loop, but unfortunately that doesn't apply to your example because it's a static method.
另一种选择是使用不是无限循环的循环覆盖该方法,但不幸的是,这不适用于您的示例,因为它是一个静态方法。
回答by IvoC
Your kind of problem looks like a Threading problem. But still, it is now a a good practice to include a stopping flag even in threads
你的问题看起来像一个线程问题。但是,即使在线程中包含停止标志现在也是一个好习惯
回答by rollstuhlfahrer
You cannot stop this from outside of this class. If you use inheritance you can overwrite your loop, but without abort-flag you won't be able to do so.
你不能在这门课之外阻止这件事。如果您使用继承,您可以覆盖您的循环,但没有 abort-flag 您将无法这样做。