株式会社イーブ|未経験・転職の方も就職可能。Javaプログラマー育成のエキスパート

HOMEJAVA技術者育成システム開発求人情報個人情報保護

第 48 回 ~ マルチスレッド編 CompletionServiceインターフェース ~

トップページ > Java技術者育成 > Javaワンポイント > 第 48 回 ~ マルチスレッド編 CompletionServiceインターフェース ~

今回のテーマは「CompletionService」です。


今回は複数の非同期処理の実行を考えてみます。
複数の非同期処理を実行した場合、その処理が完了する順番はわかりません。
Futureのgetメソッドは非同期処理の完了を待機するので、複数の非同期処理を実行した場合、遅い処理の完了を待機する可能性があります。
CompletionServiceインターフェースを実装するExecutorCompletionServiceは処理結果をキューに格納することで、完了した順に取得することができます。
このキューにはBlockingQueueが使用されます。


次のサンプルコードはファイルを読み込むタスクを実行し、読み込んだ結果を出力するプログラムです。(J2SE5.0以上対応)



import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;


public class Main {


    public static void main(String[] args) throws Exception {
        File[] files = { new File("input1.csv"), new File("input2.csv") };
        ExecutorService executorService = Executors.newCachedThreadPool();
        CompletionService<List<String>> completionService = new ExecutorCompletionService<List<String>>(executorService);
        for (File file : files) {
            completionService.submit(new ICallable(file));
        }
        executorService.shutdown();
        for (int i = 0; i < files.length; i++) {
            Future<List<String>> future = completionService.take();
            List<String> list = future.get();
            for (String string : list) {
                System.out.println(string);
            }
        }


    }


}


class ICallable implements Callable<List<String>> {


    private File file;


    public ICallable(File file) {
        this.file = file;
    }


    public List<String> call() throws Exception {
        List<String> list = new LinkedList<String>();
        BufferedReader bufferedReader = null;
        try {
            bufferedReader = new BufferedReader(new FileReader(file));
            while (bufferedReader.ready()) {
                list.add(bufferedReader.readLine());
            }
        } finally {
            if (bufferedReader != null) {
                bufferedReader.close();
            }
        }
        return list;
    }


}



今回は2つのファイルを読み込みます。
takeメソッドは完了済みタスクを表すFutureを取得し、そのFutureをキューから削除します。
どちらのファイルの読み込みが先に完了するかはわかりませんが、完了した順にキューに格納されるので、完了した順に読み込んだ結果を出力できます。


[Javaワンポイント]内の前後の記事
第 49 回 ~ シンクロナイザ編 CountDownLatch ~
→ 第 48 回 ~ マルチスレッド編 CompletionServiceインターフェース ~
第 47 回 ~ マルチスレッド編 ScheduledExecutorServiceインターフェース ~


■更新日時での前後の記事
4月22日 お天気
→ 第 48 回 ~ マルチスレッド編 CompletionServiceインターフェース ~
受付より vol.45