如何中断无限循环
虽然我知道提问会有点傻,但我还是想更多地询问它的技术观点。
无限循环的一个简单示例:
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; } }