4

私のコードには、ExecutorService固定スレッド プールで実装されたスレッド プールがあります。プールによって実行されるタスクのほとんどは非常に短いですが、約 20 ~ 30 秒という長時間実行されるタスクが 1 つある場合があります。このタスクを実行すると、新しいタスクは実行されず、長時間実行されているタスクが完了したときにのみ再開されます。

プールは 20 に設定されているため、実行中のスレッドが 2 つだけでこれを再作成できるため、問題はありません。最初は長時間実行され、2 番目はスタックします。

なぜ動かなくなったのか頭を悩ませていたのですが、に切り替えnewFixedThreadPool()newCachedThreadPool()ボトルネックが解消されました。これが私が行った唯一の変更です。

この動作は理にかなっていますか? コードは正常に動作するように見えるので、変更を維持すると思います。私が理解している限り、多くの短いタスクを実行している場合は、キャッシュ スレッド プールを使用する方が良いと思いますが、なぜ固定プールがハングしてそこにあるのか疑問に思っていました。それを修正する方法は?

また、固定からキャッシュに切り替えた場合、副作用が発生する可能性はありますか?

ありがとう。

4

1 に答える 1

0

newCachedThreadPool()は Integer.MAX_VALUE スレッド数の実行を許可するため、より多くのスレッドが同時に実行される可能性があります。

コードを見ずに副作用を推測するのは困難です。

しかし、私が思うに、スレッド数を増やすことで問題が解決した場合、ロックがかかっている可能性が高くなります。

たとえば、4 つのリソース A、B、C、D と 4 つのタスクがあるとします。

1) 短い TaskA にはリソース A が必要
2) 短い TaskB にはリソース B が必要
3) 短い TaskC にはリソース C が必要
4) 長い TaskD にはリソース A と D が必要

したがって、ある瞬間に次の状況が発生します。

Thread1: TaskA await for resource A
Thread2: TaskD has A and D and running

TaskB wait in Queue
TaskC wait in Queue

プルを無制限のスレッド数でプルするように変更する場合、または多くの許可されたスレッドを持つ固定スレッド プールを使用する場合:

Thread1: TaskA await for resource A
Thread2: TaskD has A and D and running
Thread3: TaskB has resource B
Thread4: TaskC has resource C

そのため、スレッドの 1 つが別のスレッドによってブロックされていますが、他のすべてのタスクはロックなしで実行されるため、それを確認することはできません。

于 2013-06-27T17:48:50.550 に答える