【Java】【非同期】ExecutorService / Runnableインタフェース

Executors

ExecutorService

`#`クラス名概要
1newSingleThreadExecutor単一スレッドを作成する
2newFixedThreadPool固定数のスレッドを再利用するスレッドプールを作成する
3newCachedThreadPool必要に応じ、新規スレッドを作成するスレッドプールを作成する。60 秒間使用されなかったスレッドは、終了して、キャッシュから削除される。

終了の仕方 shutdown() / shutdownNow()

 * shutdown()    : 依頼してあるタスクが終了したら終了
 * shutdownNow() : 直ちに終了

参考文献

* 図が載ってて分かりやすい
http://waman.hatenablog.com/entry/20120122/1327241289
* 正しい終了手順を説明
http://gurimmer.lolipop.jp/daihakken/2012/01/27/javaexecutorservice%E3%81%AE%E6%AD%A3%E3%81%97%E3%81%84%E7%B5%82%E4%BA%86shutdown%E3%81%AE%E4%BB%95%E6%96%B9/
http://swimmingpython.net/blog/?p=599

Runnableインタフェースを使用した場合

 * ExecutorService.execute()

サンプル1

SampleThreadPool.java

import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
//import java.util.concurrent.TimeUnit; // ★★

public class SampleThreadPool {

   private static class Task implements Runnable {
      private Integer sleepTime;

      public Task(Integer sleepTime) {
         this.sleepTime = sleepTime;
      }

      @Override
      public void run() {
         try {
            Thread.sleep(this.sleepTime * 1000);
            System.out.println(
                  Thread.currentThread().getId() + " : " + new Date());
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
      }
   }

   public static void main(String[] args) throws InterruptedException {
      ExecutorService executorService = Executors.newFixedThreadPool(2);
      try {
         System.out.println("task start " + new Date());
         executorService.execute(new Task(10));
         executorService.execute(new Task(3));
      } finally {
         executorService.shutdown();
         //executorService.awaitTermination(1, TimeUnit.MINUTES); // ★★
      }
      System.out.println("Done : " + new Date());
   }
}

出力結果

task start Tue Jun 24 23:05:15 JST 2014
Done : Tue Jun 24 23:05:15 JST 2014
11 : Tue Jun 24 23:05:18 JST 2014
10 : Tue Jun 24 23:05:25 JST 2014

補足:時間を決めてタスク完了を待つ場合

awaitTermination
 * 万が一スレッドが長時間終了できなかった場合用のブロック処理。
 => 指定時間にタイムアウトで終わらせることが可能。

出力結果

 * ★★の行のコメントを外すと以下のように出力結果が変わった。

task start Tue Jun 24 23:31:02 JST 2014
11 : Tue Jun 24 23:31:05 JST 2014
10 : Tue Jun 24 23:31:12 JST 2014
Done : Tue Jun 24 23:31:12 JST 2014


関連記事

ExecutorService / Callableインタフェース

http://blogs.yahoo.co.jp/dk521123/34213161.html

java.util.concurrent

java.util.concurrent について

http://blogs.yahoo.co.jp/dk521123/32538961.html

CountDownLatch ~カウントダウンラッチ~

http://blogs.yahoo.co.jp/dk521123/33538428.html

ExecutorService

http://blogs.yahoo.co.jp/dk521123/33665815.html

ScheduledExecutorService ~スケジューラ~

http://blogs.yahoo.co.jp/dk521123/33934102.html

タイマー

TaskTimer

http://blogs.yahoo.co.jp/dk521123/33926465.html