概要
ExecutorService
インタフェースを実現したインスタンスへの参照を戻すファクトリメソッドを用途別に提供するクラスである。
主なメソッド
-
newSingleThreadExecutor()
メソッド -
newFixedThreadPool()
メソッド -
newCachedThreadPool()
メソッド
newSingleThreadExecutorメソッド
単一のスレッドプールを作成する。
例
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SingleThreadExecutorExample {
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
// タスクを実行
executorService.execute(() -> {
System.out.println("Task 1 executed by thread: " + Thread.currentThread().getName());
});
executorService.execute(() -> {
System.out.println("Task 2 executed by thread: " + Thread.currentThread().getName());
});
executorService.execute(() -> {
System.out.println("Task 3 executed by thread: " + Thread.currentThread().getName());
});
// ExecutorServiceを終了する
executorService.shutdown();
}
}
上記の例では、newSingleThreadExecutor()
メソッドを使用してExecutorService
のインスタンスを作成している。このスレッドプールはシングルスレッドで動作し、タスクの実行を直列化する。
execute()
メソッドを使用してタスクを送信し、非同期に実行する。各タスクはスレッドプール内の単一のスレッドによって順番に実行される。
実行結果
Task 1 executed by thread: pool-1-thread-1
Task 2 executed by thread: pool-1-thread-1
Task 3 executed by thread: pool-1-thread-1
thread-X
はスレッドの連番を示している。
タスクはスレッドプール内の単一のスレッドによって直列に実行されていることがわかる。
newFixedThreadPoolメソッド
指定された数のスレッドを持つ固定サイズのスレッドプールを作成するための静的メソッドである。
例
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class FixedThreadPoolExample {
public static void main(String[] args) {
int nThreads = 3;
ExecutorService executorService = Executors.newFixedThreadPool(nThreads);
// タスクを実行
executorService.execute(() -> {
System.out.println("Task 1 executed by thread: " + Thread.currentThread().getName());
});
executorService.execute(() -> {
System.out.println("Task 2 executed by thread: " + Thread.currentThread().getName());
});
executorService.execute(() -> {
System.out.println("Task 3 executed by thread: " + Thread.currentThread().getName());
});
// ExecutorServiceを終了する
executorService.shutdown();
}
}
nThreads
パラメータは、スレッドプール内のスレッド数を示す。このスレッドプールは3つのスレッドを持ち、固定サイズのスレッドプールとなる。
スレッドプール内のスレッドは再利用され、必要に応じて新しいタスクを処理する。
実行結果
Task 1 executed by thread: pool-1-thread-1
Task 2 executed by thread: pool-1-thread-2
Task 3 executed by thread: pool-1-thread-3
pool-1
はスレッドプールの識別子を示している。thread-X
を見ると、タスクはスレッドプール内のスレッドによって並列に実行されていることがわかる。
newCachedThreadPoolメソッド
可変サイズのスレッドプールを作成するための静的メソッドである。
例
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CachedThreadPoolExample {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
// タスクを実行
executorService.execute(() -> {
System.out.println("Task 1 executed by thread: " + Thread.currentThread().getName());
});
executorService.execute(() -> {
System.out.println("Task 2 executed by thread: " + Thread.currentThread().getName());
});
executorService.execute(() -> {
System.out.println("Task 3 executed by thread: " + Thread.currentThread().getName());
});
// ExecutorServiceを終了する
executorService.shutdown();
}
}
このスレッドプールは可変であり、必要に応じてスレッドを動的に作成および再利用する。
スレッドプール内のスレッドは自動的に管理され、一定時間が経過すると自動的に破棄される。
実行結果
Task 1 executed by thread: pool-1-thread-1
Task 2 executed by thread: pool-1-thread-2
Task 3 executed by thread: pool-1-thread-3
タスクはスレッドプール内のスレッドによって並列に実行される。
newCachedThreadPool()
メソッドはスレッド数の上限を指定しないため、大量のタスクが同時に送信されるとスレッド数が増えてしまい、システムのリソースを消費する可能性がある。
newFixedThreadPoolメソッドとの比較
実行順序に違いがある。
-
newFixedThreadPool
メソッド:
スレッド数が固定されているため、タスクの実行が完了するまで待機する必要がある。
タスクの実行順序はキューに追加された順番に従うため、結果として実行順序が保持される。 -
newCachedThreadPool
メソッド:
可変サイズのスレッドプールが作成され、スレッドプールは必要に応じてスレッドを作成および再利用される。タスクが同時に実行される場合、タスクの完了時間やスレッドの使用状況によって異なる場合があるため、実行順序は保証されない。
ExecutorService
は、必要に応じてshutdown()
メソッドを呼び出してスレッドプールを終了する必要がある。
これにより、プログラムの終了時にスレッドプールが適切にシャットダウンされ、リソースの解放が行われる。