2016-12-13 6 views
1

私は別のスレッドからいくつかのコードを実行し、一定の時間が経過した後にタイムアウトさせたいとします。また、他のコードを定期的に実行できるようにしたい(つまり、出力を更新するなど)。スレッドを開始できませんでしたか?

これは私がそれをやっているか、本質的である:、私の質問がある

Thread operation = new Thread() { ... }; 
operation.start(); 

// Check if Thread is still alive every 100ms 
for (int i = 0; i < timeout/100; i++) { 
    somethingToDoWhileWaiting(...); 
    if (!operation.isAlive()) { 
     break; // Thread is dead so we can end early 
    } 
    Thread.sleep(100); 
} 

if (operation.isAlive()) { 
    operation.interrupt(); // timed out 
} 

スレッドは(例外のいくつかの並べ替えをスローせず)を起動、またはそれが持っていないかもしれないということができないことをどのような方法があります私はそれが生きていることをチェックしたい時までに始まった?

  1. 私はoperation.start()を呼び出し、エラーがスローされません:のように

    、という可能性があります。

  2. は私がループに入ると、それは

  3. 生きている場合、それは(それがまだ開始されていないか、舞台裏でエラーがあっただいずれかのため)ではありません確認してください?そのショート

、スレッドが終了したことを確認する良い方法がある(または、それが正しく起動だということは - 私はそれが生きていたまでループを考えたが、私はそれについて同じ悩みを持っていますか)?

+2

JDKの将来のAPIをチェックアウトする必要があります。 –

答えて

2

ExecutorsおよびFuturesは、他の人が指摘しているように行く方法です。

しかし、具体的

が、それは私がそれをですチェックしたい時で開始していない可能性がありますことを、スレッドが(例外のいくつかの並べ替えをスローせずに)開始することができないことをどのような方法があるか、あなたの質問に答えるために生きている?

回答:スレッドは例外をスローまたはスローします。期間。

Thread.start()メソッドのマニュアルhereを確認してください。

これに加えて、ここには開始メソッドのコードがあります。あなたはそれを通ってそれを感じることができます。

public synchronized void start() { 
    /** 
    * This method is not invoked for the main method thread or "system" 
    * group threads created/set up by the VM. Any new functionality added 
    * to this method in the future may have to also be added to the VM. 
    * 
    * A zero status value corresponds to state "NEW". 
    */ 
    if (threadStatus != 0) 
     throw new IllegalThreadStateException(); 

    /* Notify the group that this thread is about to be started 
    * so that it can be added to the group's list of threads 
    * and the group's unstarted count can be decremented. */ 
    group.add(this); 

    boolean started = false; 
    try { 
     start0(); 
     started = true; 
    } finally { 
     try { 
      if (!started) { 
       group.threadStartFailed(this); 
      } 
     } catch (Throwable ignore) { 
      /* do nothing. If start0 threw a Throwable then 
       it will be passed up the call stack */ 
     } 
    } 
} 

private native void start0(); 

これが役に立ちます。

-2

Thread.join()を使用する - スレッドが終了するまでブロックされます。

+0

これは最も基本的なケースでは機能しますが、必ずしも実行をブロックする必要はありません。その間にやりたいことがあるかもしれません。これを反映するように編集します:) – dram

4

これはExecutorServiceの先物を利用するには絶好の場所である:あなたのコアの質問に関しては

Runnable task = new Runnable() { ... }; 
ExecutorService executor = Executors.newFixedThreadPool(1); 
Future<Void> future = executor.submit(task); 

// Check if Thread is still alive every 100ms 
for (int i = 0; i < timeout/100; i++) { 
    somethingToDoWhileWaiting(...); 
    if (!future.isDone()) { 
     break; // Thread is dead so we can end early 
    } 
    Thread.sleep(100); 
} 

if (!future.isDone()) { 
    future.cancel(true); 
} 

:スレッドは、オペレーティング・システムのスケジューラのなすがままにされています。スレッドになることはありません。しかし、OSスケジューラは非常に優れているので、これは非常に困難です。スレッドが作業をせずにかなりの時間が経過すると、コードにバグが発生する可能性がより高くなります。

+1

'Void'を返すと宣言されていても、Futureに対して' get() 'を呼び出さないでください。それ以外の場合は、スレッド内から例外がスローされ、捕捉されることはありません。そしてはい、 'get()'はブロッキング呼び出しです。このため、通常はコールバックメソッド内から呼び出します。 –

関連する問題