第六章 (1): Executor

1時半就寝、7時半起床。たまたま仕事が普通の時間に終わったので、読書した後に深夜に遊んでしまった。ピアノ、欲しいなー。買おうかなー。

Executorフレームワーク

タスクの実行と依頼を分離するフレームワーク。プロデューサ・コンシューマパターンを実現する。種々のスレッドプールを構築し、スループットと安定性を両立した並行処理実行機能を提供する。
Executorsクラスがスレッドプールのstaticファクトリメソッドを幾つも持っている。

  • newFixedThreadPool: プールサイズを一定に保つスレッドプール
  • newCachedThreadPool: 処理要求に応じてプールサイズが変化するスレッドプール
  • newScheduledThreadPool: タスクの遅延開始と周期実行をサポートする、固定サイズのスレッドプール

ExecutorService

JVMはデーモンではない全てのスレッドが終了しないと終われない。Executorはスレッドを生成して並行処理を実行するが、このままではいつまでも終われない。
→ Executorを継承して、ライフサイクルを管理出来るようにしたインターフェースがExecutorService。

private static class LifecycleServer {

	private final ExecutorService executor = Executors.newFixedThreadPool(POOL_SIZE);

	public void start() throws IOException {
		ServerSocket ss = new ServerSocket(PORT);
		while (!executor.isShutdown()) {
			try {
				final Socket s = ss.accept();
				executor.execute(new Runnable() {
					public void run() {
						handleRequest(s);
					}
				});
			} catch (RejectedExecutionException e) {
				if (!executor.isShutdown()) {
                                        // Executorが生きていてタスクが却下された
					log("task rejected:" + e);
				}
			}

		}

	}
         
        ...
}

タスクの遅延実行/周期実行

Timerクラスはシングルスレッドなので、TimerTask実行のタイミングが不正確だったり問題があるので、今後は

  • ScheduledThreadPoolExecutor
  • DelayQueue

などを使って実装すべき。