如何中断无限循环

big*_*ero 24 java loops infinite-loop

虽然我知道要问一点有点傻,但我还是想更多地询问它的技术观点.

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

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

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

Dav*_*ant 49

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

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

  • `System.setOut(null)`就足够了. (8认同)
  • @Marko我希望为了编程世界中所有神圣的事情,这是一个纯粹的学术问题.;) (6认同)
  • @maba这是一个非常牵强的假设.当提问者发布涉及"main"的代码时,我们可以肯定他的意思是他的入口点.否则,为什么不假设有一个AOP基础结构允许向每个`PrintStream.println`调用注入任意代码,或者`System`实际上是一个`import my.package.System`,它具有完全不相关的实现? (2认同)
  • @Marko我想你可能过多地研究方法问题了.为什么不将Thread.stop作为不同的答案发布,包括Thread访问. (2认同)

Sub*_*der 26

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

   for(;!cancelled;) /*or while(!cancelled)*/{
       System.out.println("Stackoverflow");
   }
Run Code Online (Sandbox Code Playgroud)

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

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;
      }
}
Run Code Online (Sandbox Code Playgroud)

  • 不要忘记宣布取消为volatile (13认同)
  • 也许你会希望`cancel()`方法也是`static`.然后你不需要一个'LoopInfinite`对象来阻止循环. (4认同)
  • @maba - dude ur r8在这方面.这是一个片段而不是实际的实现.实际实施可能需要进行一千次更改. (2认同)

Joe*_*erg 6

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

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

    Thread loop = new Thread() { 

        public void run() {
            Thread.currentThread().setName("loop");
            while(true) {
                System.out.print(".");
            }
        }
    }.start();
Run Code Online (Sandbox Code Playgroud)

然后在其他一些课程中:

    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();
        }
    }
Run Code Online (Sandbox Code Playgroud)

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

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

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


Dmi*_*nko 5

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

while(cond) {}
Run Code Online (Sandbox Code Playgroud)

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