1

コメント付きの次のスニペットを見てください。

try {
  Thread.sleep(20000); // Foo thread sleeps for 20 seconds
  System.out.println("After the sleep statement");
} catch(Exception exc) {
    exc.printStackTrace();
  }

// It has been 12 seconds since the thread went to sleep and....I interrupt

Foo.interrupt(); // exception gets thrown and the code in the catch block gets executed

sleep ステートメントの後に次のステートメントを実行する方法はありますか? いつかスレッドを目覚めさせて、それを継続させたいと思っています。これに対する考え/方法はありますか?

4

3 に答える 3

1

The Java Tutorialsには非常によく表現された段落があります。

割り込みは、スレッドが実行していることを停止し、別のことを行う必要があることを示すものです。スレッドが割り込みにどのように応答するかを正確に決定するのはプログラマ次第ですが、スレッドが終了することは非常に一般的です。これは、このレッスンで強調されている使用法です。

スレッドを確実に停止して開始することは、並行アプリケーションを設計する上で重要な部分です。また、割り込みを目的を変更して目的を変更することもできますが、スレッドの終了を要求するという最も一般的な目的のために割り込みを残すと、コードの信頼性が向上し、他のユーザーにとって保守が容易になります。これは、20 秒のタイムアウトが終了する前にユーザーがアプリをシャットダウンすることを決定した場合に、おそらくやりたいことです。

では、元の問題を解決する方法 - あるスレッドが別のスレッドに作業を開始する時期であることを示すことができます。以下のクラスは、CountDownLatch を使用してこの問題を解決する方法を示しています。

新しいフー:

class Foo extends Thread
{

   CountDownLatch latch = new CountDownLatch(1);

   @Override
   public void run()
   {
      try
      {
         boolean early = latch.await(20, TimeUnit.SECONDS);
         System.out.println("Doing work " + (early ? "right away" : "after delay"));
         // do real work here...
      }
      catch (InterruptedException e)
      {
         System.out.println("Interrupt detected. Exiting thread...");
      }
   }

   public void goAhead()
   {
      latch.countDown();
   }
}

「スリープ」を取り除き、ラッチ オブジェクトの await メソッドの呼び出しに置き換えます。foo を機能させるには、次のように呼び出します。

foo.goAhead();  // prints out "Doing work right away"

これにより、ラッチがカウントダウンします。「await」の呼び出しは、例外をスローして true を返すことなく、すぐに終了します。

foo をシャットダウンするには、次を使用します。

foo.interrupt();  // prints out "Interrupt detected..."

これにより、await はスリープと同様に InterruptedException をスローします。

または何もしないでください。await の呼び出しは 20 秒後にタイムアウトになり、例外をスローせずに false を返します。Fooは「遅延後に仕事をしています」と出力します

この設計の長期的な利点の 1 つは、「作業中」に他のブロッキング メソッドを呼び出す必要がある場合があることです。Interrupt を使用してそれらのいずれかに割り込むことができ、予期しないイベントに応答してスレッドを確実にシャットダウンするのに役立ちます。

于 2012-10-07T20:25:14.663 に答える
1

これがあなたが望むものかどうかわかりませんか?

try {
  Thread.sleep(20000); // Foo thread sleeps for 20 seconds
  System.out.println("After the sleep statement");
} catch(InterruptedException exc) {
    System.out.println("Sleep was interrupted");
} catch(Exception exc) {
    exc.printStackTrace();
}

sleep()InterruptedException中断されたときにスローします。そのため、構成された 20 秒間スリープすることができた場合にのみ呼び出さ"Sleep was interrupted"れてinterrupt()いる間に出力されます。"After the sleep statement"sleep()

通常どおり返されるかスローされるかを気にせずsleep()、作業を続行する場合は、 empty でラップしますtry-catch

public void interruptibleSleep(long millis) {
    try {
      Thread.sleep(millis);
    } catch(InterruptedException exc) {}
}

そして、Thread.sleep(20000)callの代わりにinterruptibleSleep(20000):

interruptibleSleep(20000);
System.out.println("After the sleep statement");
于 2012-10-07T16:43:27.350 に答える
1

私はあなたが混乱していると思います。これが何が起こるかです

public void run() { 
  // This executes as soon as the thread is run
  try {
     // We decide to sleep for UPTO 20 seconds
     Thread.sleep(20000); 

     // Code here executes ONLY if we managed to sleep for 20 seconds without 
     // interruption

  } catch(InterruptedException exc) {
     // Code here executes ONLY if we were interrupted
  } catch(Exception exc) {
     // This shouldn't ever execute in theory
  }

  // Code here ALWAYS executes after the sleeping (and ONE of the two blocks) 
  // whether or not it was interrupted.
}
于 2012-10-07T16:55:09.597 に答える