ITエンジニアの技術メモ

神奈川在住のITエンジニアの備忘録です。主にプログラミング(Perl, Java など)やネットワーク技術について、仕事などを通じて学んだことを自分の中で整理するためにゆるゆると書いています。誰かのご参考になれば幸いです。

JavaのExecutorServiceで簡単マルチスレッド

Javaでマルチスレッドなプログラムを書く場合、Java1.5から導入された ExecutorService を使うと簡単に書ける。
以下は ExecutorService を使った簡単なサンプルプログラムである。

import java.util.Date;
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;

public class FutureSample {

    public static void main(String[] args) {
        try{
            FutureSample futureSample = new FutureSample();
            futureSample.exec();
        }
        catch(Exception ex){
            System.out.println(ex.getMessage());
            System.out.println(ex.getStackTrace());
        }
    }

    private void exec() throws InterruptedException, ExecutionException {
        //--------------------------------
        // Definition of a task(Callable).
        //--------------------------------
        Callable<Date> task = new Callable<Date>() {
            public Date call() throws InterruptedException {
                System.out.println("Task started."); /*---(3)---*/
                Thread.sleep(3000);
                Date time = new Date();
                System.out.println("Task Ended."); /*---(4)---*/
                return time;
            }
        };

        ExecutorService executor = Executors.newSingleThreadExecutor();

        // Execute the task and get a future for the task.
        System.out.println("Execute a task..."); /*---(1)---*/
        Future<Date> future = executor.submit(task);

        // Other tasks can be done with the task here, and this fact is important for using Future.
        System.out.println("Execute other task."); /*---(2)---*/
        Thread.sleep(5000);
        System.out.println("Other task finished."); /*---(5)---*/

        // Get the result of the task if it has been done. Otherwise this thread waits here.
        Date time = future.get();
        System.out.println("Time(Task result) is " + time); /*---(6)---*/

        executor.shutdown();
    }
}

これを実行すると、ソース中のコメントに書いた番号(1~6)の順に出力される。


ここでのポイントは、

        Future<Date> future = executor.submit(task);

と書くだけで、task を非同期に実行でき、結果は任意のタイミングで、

        future.get();

で取り出せるということ。もちろん、future.get() した時点で task が終了していなければここで待たされる。

executor に task を submit するだけで非同期にタスクを実行できる(マルチスレッドを実現できる)なんて便利ですね~。