import java.util.Arrays; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; // ネタ元はこちら → http://d.hatena.ne.jp/language_and_engineering/20120205/p1 // この実装例では、タスクn個に対してスレッド1個でありスレッドの生成破棄コストは小さくできている。 // Executors.newSingleThreadExecutorによって依頼されたタスクが逐次実行されることが保証されている。 // またスレッドが異常終了してもスレッドを再度起動する仕組みがある。 // 先行タスクで反映したメモリI/O操作は後続タスクで可視になるようになっている。 public class Main { private static class SumTask implements Callable { private int first; private int last; SumTask(int first, int last) { this.first = first; this.last = last; } @Override public Integer call() throws Exception { long id = Thread.currentThread().getId(); System.out.println(String.format("thread id = %d, start %d %d", id, first, last)); int sum = 0; for (int i = first; i <= last; i++) { sum += i; } System.out.println(String.format("thread id = %d, end %d %d", id, first, last)); return sum; } } /** * @param args */ public static void main(String[] args) { new Main().start(); } private void start() { ExecutorService executor = Executors.newSingleThreadExecutor(); try { // invokeAllのコレクションで列挙したタスクの順序どおりに逐次実行される List> invokeAll = executor.invokeAll(Arrays.asList( new SumTask(1, 100), new SumTask(101, 200))); for (Future future : invokeAll) { System.out.println(future.get()); } executor.shutdown(); // このコードの場合は多分以下はいらないはずだが、お行儀よく振る舞うなら必要かも。 // while (executor.awaitTermination(5, TimeUnit.MILLISECONDS) == false) { // System.out.println("waiting..."); // Thread.sleep(100); // } } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } }