Java 如何中断无限循环

Java 如何中断无限循环,java,loops,infinite-loop,Java,Loops,Infinite Loop,虽然我知道这样问有点傻,但我还是想问更多关于它的技术观点 无限循环的一个简单示例: public class LoopInfinite { public static void main(String[] args) { for (;;) { System.out.println("Stack Overflow"); } } } 如何从类外部中断(停止)这个无限循环(例如,借助继承)?您不能从类外部停止它。如果使用继承,则

虽然我知道这样问有点傻,但我还是想问更多关于它的技术观点

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

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

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

您不能从类外部停止它。如果使用继承,则可以覆盖循环,但如果没有中止标志,则无法覆盖循环。

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

while(cond) {}

从另一个地方将其设置为false是一个非常开放的问题,但停止这样的循环很可能需要从另一个线程进行操作。然后,另一个线程需要设置一些变量,您的无限循环可以定期检查这些变量,以及该变量是否具有特定值;打破循环。

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

   for(;!cancelled;) /*or while(!cancelled)*/{
       System.out.println("Stackoverflow");
   }
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();

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

您的问题看起来像是一个线程问题。但是,现在,即使在线程中包含停止标志也是一种很好的做法。

我们可以使用来实现它e> volatilevariable,我们将在线程外更改它并停止循环

   for(;!cancelled;) /*or while(!cancelled)*/{
       System.out.println("Stackoverflow");
   }
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();
这是编写无限循环的更好方法

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

写这封信我都觉得很脏,但是

从另一个线程,您可以使用
PrintStream
实现调用
System.setOut()
,当您调用
println()时,它会抛出
RuntimeException

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

在这里,为了便于识别,我将线程命名为有问题的循环

    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();
        }
    }
请注意,在我的示例中,我假设两个线程在同一个线程组中。不能保证会出现这种情况,因此您可能需要遍历更多的组

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


我给你的唯一建议是,即使在发布了这篇文章之后,也不要这样做。你可以这样做,但是你真的不应该添加一个变量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;
    }
}
}

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


因此,这是一种让后台运行循环的简单方法。

您可以通过请求thread.currentThread()来保持对该线程[main]的继承引用的静态引用来中断该线程,如下所示

公共类循环无限{
公共静态线程main=null;
公共静态void main(字符串[]args){
main=Thread.currentThread();
对于(;;)
System.out.println(“Stackoverflow”);
}
}
要终止,您可以从其他线程调用它

LoopInfinite.main.interrupt();
但只有当两个线程都是同一组的一部分时,它才会工作。否则调用线程将得到

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;

    }
  }  

在这种情况下,你不能使用继承,因为它是一个静态方法。我的意思是,在一个简单的类中,这个无限循环代码是被编写的,那么我可以用什么方式停止这个无限函数呢?别忘了将cancelled声明为volatileMaybe,你可能想要
cancel()
方法也是
静态的
。那么你不需要
LoopInfinite
的对象就可以停止循环。@maba-dude u r r8在此上下文中。这是一个片段,不是实际实现。实际实现可能需要数千个更改。@Buhb:除非你有其他内存,否则没有必要这样做ng从多个线程读取/写入必须与“取消”标志一致。如果这是您的情况,最好使用锁/监视器或其他重量级并发控制,因为“volatile”本身可能不会帮助您。如果您正确使用锁,volatile在大多数情况下都是不必要的案例。除非您真正了解自己在做什么,直到CLR内存模型的级别以及存储/释放重新排序是什么,否则请避免使用它。只需使用锁。为什么要为此使用任何局部变量,而不是本机中断()-支持?只需编写
,而(!isInterrupted())
将继续,直到有人调用中断()为止-为了简单起见,我不使用main();在一个简单的类中,只编写了这段无限代码,…然后,如果您无法更改代码,您必须找到它运行的线程,这可以通过创建时对它进行引用,也可以循环遍历所有线程,并尝试确定哪一个是合适的线程,但这可能是错误的困难。如果您更清楚地指定具体情况(循环是如何启动的,您需要发生什么,等等,例如,循环是由您控制的代码启动的?
System.setOut(null)
就足够了。@MarkoTopolnik可能是另一个具有<