2

この簡単な質問があります:

サービスでは、互いに独立してさらに 2 つのスレッドを実行する必要があり、それらを実行するにはウェイクロックが必要です。例を挙げます:

   wl.aquire();

    if (true) {
        mExecutorService.execute(thread1);
    }

    if (true) {
        mExecutorService.execute(thread2);
    }
   wl.release();

したがって、この場合、2 つのスレッドが開始されるとウェイクロックが解放されますか、それとも終了するのを待ちますか?

そうでない場合は、実行中にウェイクロックを維持し、最後のスレッドが終了したときにのみ解放する必要があります。どうやってやるの?スレッドの本体内で新しいウェイクロックを取得する必要がありますか?

ありがとうございました

4

3 に答える 3

4

Executorexecute()のドキュメントによると、「指定されたコマンドを将来のある時点で実行します。コマンドは、Executor 実装の裁量で、新しいスレッド、プールされたスレッド、または呼び出し元のスレッドで実行できます。」

したがって、使用している具象 Executor によって異なります。

submit()Executor に新しいジョブを与えるために使用することになっていると思います。

Executor に固執する場合、get()返される Future の呼び出しはsubmit()、結果が利用可能になるまでブロックされます。

したがって、次のように呼び出すことができます。

Future<Result> result_1 = mExecutorService.execute(Runnable1);
Future<Result> result_2 = mExecutorService.execute(Runnable2);

result_1.get();
result_2.get();

または、2 つのスレッドを開始して、それらが終了するのを待つこともできます。

Thread t1 = new Thread(Runnable1);
Thread t2 = new Thread(Runnable2);
t1.start();
t2.start();

t1.join();
t2.join();

お役に立てれば。

于 2012-11-12T14:48:25.463 に答える
1

AsyncTaskまたはバックグラウンド スレッドからこのコードを実行していると仮定します。[Thread.join()]への呼び出しの前にすべてのスレッドを呼び出すことができますwl.release();

詳細については、このリンクをチェックしてくださいjoin()

EDIT1: エグゼキュータでは、awaitTermination()を長い待機値とともに使用して、すべてのタスクが完了するのを待つこともできます。次のコードは、公式のJava docからのものです。

void shutdownAndAwaitTermination(ExecutorService pool) {
   pool.shutdown(); // Disable new tasks from being submitted
   try {
     // Wait a while for existing tasks to terminate
     if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
       pool.shutdownNow(); // Cancel currently executing tasks
       // Wait a while for tasks to respond to being cancelled
       if (!pool.awaitTermination(60, TimeUnit.SECONDS))
           System.err.println("Pool did not terminate");
     }
   } catch (InterruptedException ie) {
     // (Re-)Cancel if current thread also interrupted
     pool.shutdownNow();
     // Preserve interrupt status
     Thread.currentThread().interrupt();
   }
 }
于 2012-11-12T14:33:51.740 に答える
0

http://developer.android.com/reference/android/os/PowerManager.WakeLock.htmlを参照してください。正しい方法は、実行中の 2 つのスレッド内でウェイクロックを取得することです。サンプル コードを考えると、スレッド 1 とスレッド 2 内にウェイクロックを格納するためのメンバー変数と、おそらく次のようにウェイクロックを渡す何らかの方法が必要になります。

thread1.setWakelock(wl);
thread2.setWakelock(wl);

class Thread implements Runnable {
    PowerManager.Wakelock mWakelock;
    void setWakelock(PowerManager.Wakelock wl) {
        mWakelock = wl;
    }
}

次に、thread1 と thread2 内で、次のものが必要になります。

run() {
    mWakelock.acquire();
    ... your existing code here ...
    mWakelock.release();
}

wake lock はデフォルトで参照カウントされるため、これは機能することに注意してください。PowerManager.WakeLock.setReferenceCounted() を参照してください。

thread.join() を使用してスレッドが終了するのを待つのは間違っています。UI スレッドがブロックされ、ANR が発生します。

于 2013-07-10T23:28:30.210 に答える