2018年8月11日 星期六

Callable、Future、CompletionService

※Callable、Future

ExecutorService es = Executors.newSingleThreadExecutor();
Future<String> future = es.submit(() -> "yeah!");
    
System.out.println("等一兮呢");
try {
    System.out.println(future.get());
    es.shutdown();
} catch (InterruptedException | ExecutionException e) {
    e.printStackTrace();
}

※submit 裡的參數就是 Callable

※Callable 和 Runnable 類似,但有回傳值

※Future 可以用 get() 取得 Runnable 的回傳值


※get 參數

ExecutorService es = Executors.newSingleThreadExecutor();
Future<String> future = es.submit(() -> {
    Thread.sleep(1000L);
    return "yeah!";
});
    
System.out.println("等一兮呢");
try {
    System.out.println(future.get(500L, TimeUnit.MILLISECONDS));
} catch (InterruptedException | ExecutionException | TimeoutException e) {
    e.printStackTrace();
} finally {            
    es.shutdown();
}

※如果超過 get 設定的時間,就會出現 java.util.concurrent.TimeoutException



※CompletionService

ExecutorService 有多個 Callable 時,每個 Callable 都會回傳一個Future,使用 get 取得結果時,不一定會是第一個 Future,使用 CompletionServce 可以解決這個問題

ExecutorService es = Executors.newFixedThreadPool(3);
CompletionService<String> ecs = new ExecutorCompletionService<>(es);
    
for (int i = 0; i < 3; i++) {
    int temp = i;
    ecs.submit(() -> {
        Thread.sleep(new Random().nextInt(10000));
        return "嘻嘻嘻" + temp;
    });
}
    
for (int i = 0; i < 3; i++) {
    Future<String> future;
    try {
        future = ecs.take();
        System.out.println(future.get());
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    }
    
    if(i == 2) {
        es.shutdown();
    }
}

※一組執行緒,誰先執行完誰就先執行

沒有留言:

張貼留言