如何中断无限循环

虽然我知道提问会有点傻,但我还是想更多地询问它的技术观点。

无限循环的一个简单示例:

public class LoopInfinite { public static void main(String[] args) { for (;;) { System.out.println("Stack Overflow"); } } } 

如何从这个类的外部中断(停止)这个无限循环(例如,在inheritance的帮助下)?

我写这个也觉得很脏,但……

在不同的线程中,您可以使用PrintStream实现调用System.setOut() ,该实现在调用println()时会抛出RuntimeException

我们可以使用volatile变量来实现它,我们将改变ouside Thread并停止循环。

  for(;!cancelled;) /*or while(!cancelled)*/{ System.out.println("Stackoverflow"); } 

这是编写无限循环的更好方法。

 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; } } 

可以从另一个线程获取运行无限循环的线程并在其上调用中断。 你必须非常确定自己在做什么,并希望被中断的线程在被中断时表现正常。

在这里,我使用违规循环命名了线程,以便于识别。 请注意以下解决方案容易受到竞争条件的影响。

  Thread loop = new Thread() { public void run() { Thread.currentThread().setName("loop"); while(true) { System.out.print("."); } } }.start(); 

然后在其他一些课程中:

  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(); } } 

请注意,在我的示例中,我假设两个线程在同一个ThreadGroup中。 不能保证会出现这种情况,因此您可能需要遍历更多组。

如果你对此有一些控制权,那么这里一个合适的模式就是在循环声明中使用while(!isInterrupted())并使用t.interrupt()而不是t.stop()

即使在发布之后,我对你的唯一建议是不要这样做。 你可以做到,但你真的不应该这样做

我认为这是不可能的。 仅在循环内使用break 。 你可以用

 while(cond) {} 

从其他地方来说,这是假的

您可以通过向Thread.currentThread()询问,保持其对此Thread [main]的inheritance引用的静态引用来中断此线程,就像这样

 public class LoopInfinite{ public static Thread main = null; public static void main(String[] args){ main = Thread.currentThread(); for(;;) System.out.println("Stackoverflow"); } } 

要终止,您可以从其他线程调用此函数

 LoopInfinite.main.interrupt(); 

但只有当两个线程都属于同一组时,它才会起作用。 否则调用线程将获得SecurityException

你无法阻止这个课程以外的课程。 如果你使用inheritance,你可以覆盖你的循环,但没有abort-flag,你将无法这样做。

非常开放的问题,但停止这样的循环很可能需要你从另一个线程操作。 然后另一个线程需要设置一个变量,你的无限循环可以定期检查,如果变量有一定值; 突破循环。

如果不完全停止进程,您将无法中断此特定循环。 一般来说,如果你试图从外部源代码(我假设你无法控制源代码,因为如果你这样做,你可以轻松地在循环中设置一个条件,比如你可以设置一个布尔值从外部线程),您将不得不暂停正在运行的线程,无论您是通过Thread对象执行此操作(您必须以某种方式找到对它的引用,例如通过循环现有的线程 ),或者是否停止它作为一个系统过程 。

另一种选择是使用不是无限循环的循环覆盖该方法,但不幸的是,这不适用于您的示例,因为它是一个静态方法。

您遇到的问题类似于线程问题。 但是,现在,即使在线程中包含停止标志也是一种很好的做法

如果你需要一个“无限”循环,你肯定需要一个线程(否则你的应用程序将被卡住直到循环结束)。

 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(); 

所以,这是一个有后台运行循环的简单方法。

添加变量shouldBreak或可以使用getter和setter设置的东西。

 public class LoopInfinite { private boolean shouldBreak = false; public boolean isShouldBreak() { return shouldBreak; } public void setShouldBreak(boolean shouldBreak) { this.shouldBreak = shouldBreak; } public static void main(String[] args) { // Below code is just to simulate how it can be done from out side of // the class LoopInfinite infinite = new LoopInfinite(); infinite.setShouldBreak(true); for (;;) { System.out.println("Stackoverflow"); if (infinite.shouldBreak) break; } } 

}

这是我做的:

 while(Exit == false){ Scanner input = new Scanner(System.in); String in = input.next(); switch(in){ case "FindH": FindHyp hyp = new FindHyp(); float output = hyp.findhyp(); System.out.println(output); case "Exit": Exit = true; break; } }