第六章 (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
などを使って実装すべき。