24

質問するのは少しばかげていると思いますが、それでも技術的な観点についてもっと知りたいと思います。

無限ループの簡単な例:

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

このクラスの外部から(たとえば、継承の助けを借りて)この無限ループを中断(停止)するにはどうすればよいですか?

4

12 に答える 12

49

これを書いても汚い気がしますが…

別のスレッドから、を呼び出すときにをスローSystem.setOut()するPrintStream実装を使用して呼び出すことができます。RuntimeExceptionprintln()

于 2012-08-17T08:41:24.553 に答える
26

変数を使用してそれを達成できます。volatile変数を変更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;
      }
}
于 2012-08-17T08:41:09.573 に答える
6

別のスレッドから無限ループを実行しているスレッドに到達し、そのスレッドで割り込みを呼び出すことができます。ただし、何をしているのかを十分に確認する必要があります。また、中断されたスレッドが中断されたときに正しく動作することを期待してください。

ここでは、識別を容易にするために、問題のあるループを使用してスレッドに名前を付けました。次のソリューションは競合状態に対して脆弱であることに注意してください。

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

私の例では、2つのスレッドが同じThreadGroupにあると想定していることに注意してください。これが当てはまるという保証はないので、より多くのグループをトラバースする必要があるかもしれません。

これをある程度制御できる場合、ここでの適切なパターンは、while(!isInterrupted())代わりにループ宣言に含まれ、のt.interrupt()代わりに使用することですt.stop()

これを投稿した後でも、あなたへの私の唯一のアドバイスは、これをしないことです。あなたはそれをすることができます、しかしあなたは本当にすべきではありません

于 2012-08-17T08:57:28.677 に答える
5

これは不可能だと思います。ループ内でのみブレークを使用します。あなたが使うことができます

while(cond) {}

そして他の場所からそれを偽りにする

于 2012-08-17T08:38:09.170 に答える
3

このスレッド[main]への継承された参照の静的参照を保持することにより、このスレッドを中断できます。このようにThread.currentThread()から要求します。

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が発生します

于 2012-08-17T09:03:58.903 に答える
2

このクラスの外からこれを止めることはできません。継承を使用する場合、ループを上書きできますが、abort-flagがないと上書きできません。

于 2012-08-17T08:36:41.543 に答える
2

非常に未解決の質問ですが、そのようなループを停止するには、おそらく別のスレッドから操作する必要があります。次に、他のスレッドは、無限ループが定期的にチェックできる変数を設定する必要があります。また、変数に特定の値があるかどうかを確認します。ループから抜け出します。

于 2012-08-17T08:38:19.433 に答える
2

プロセスを完全に停止せずに、この特定のループを中断することはできません。一般に、外部ソースから実行しようとしている場合(ブール値など、ループ内の条件を簡単に設定できるため、ソースコードを制御できないと想定しています。外部スレッドから)、スレッドオブジェクトを介してこれを行うか(既存のスレッドをループするなどして、何らかの方法でスレッドへの参照を見つける必要があります)、実行中のスレッドを停止する必要があります。システムプロセスとして。

もう1つのオプションは、無限ループではないループでメソッドをオーバーライドすることですが、静的メソッドであるため、残念ながら、これは例には適用されません。

于 2012-08-17T08:39:24.367 に答える
2

あなたの種類の問題はスレッディングの問題のように見えます。しかし、それでも、スレッドに停止フラグを含めることは今では良い習慣です

于 2012-08-17T08:40:22.743 に答える
2

「無限」ループが必要な場合は、必ずスレッドが必要です(そうでない場合、アプリはループの終わりまでスタックします)。

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

したがって、これはバックグラウンドでループを実行するための簡単な方法です。

于 2012-08-17T09:03:04.520 に答える
1

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

}

于 2012-08-17T08:58:16.093 に答える
0

これが私がしたことです:

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;

    }
  }  
于 2016-10-21T01:14:26.193 に答える