非同期処理にはThreadを直接使わずにExecutorServiceを使用する
一個前の記事 で
MyRunnable runnable = new MyRunnable(); Thread thread = new Thread(runnable); thread.start();
みたいな感じでThread
クラスのコンストラクタにRunnable
実装したサブクラスを渡して非同期処理をしようと書いたけれど、以下の観点からおすすめできません。
- 複数Threadを作成する際、スレッド作成時間がパフォーマンスに影響を与える可能性がある。
- 作成したThreadがそのまま放置される。
そこで一度作成したスレッドを待機(プール)させ、必要に応じてスレッドを取り出してタスクを割り当て、タスクが完了したらスレッドを再度プールさせる(スレッドを再利用する)スレッドプールという仕組みを活用してパフォーマンスの向上を図ります。
スレッドプールはExecutor
クラスのメソッドで作成できます。
これによりExecutorService
オブジェクトが生成され、スレッドの実行を行います。
ExecutorService executorService = null; try { executorService = Executors.newFixedThreadPool(2); executorService.execute(new OneRunnable()); executorService.execute(new TwoRunnable()); } finally { executorService.shutdown(); }
Executors#newFixedThreadPool(int)
でスレッドプールを作成します。
execute
にRunnableオブジェクトを渡すと自動的にタスクをスレッド意に割り当てて実行されます。
Executors
は主に以下のようなメソッドを持ちます。
メソッド名 | 機能 |
---|---|
newFixedThreadPool | 引数で指定した数のスレッドを常時保持するスレッドプールを作成。 タスクは空いているスレッドに割り当てられます。 |
newCachedThreadPool | タスクを割り当てる度に新しいスレッドを生成し、そのスレッドを使いまわします。 一定時間使用されなかったスレッドは消滅します。 |
newScheduledThreadPool | タスクを一定時間ごとに実行するスレッドを持つスレッドプールを作成。 |
newSingleThreadExecutor | 1つのスレッドを使いまわすスレッドプールを作成。 割り当てられたタスクは順番に実行されます。 |