1. Future API
get()
:此方法是阻塞的;使用interrupt
的时候,打断的是当前线程,让当前线程不再阻塞的等待获取数据;并不是打断线程池中的线程;get(TimeOut)
:若是获取数据超时了,但是任务还是依旧执行,只是不再等待任务的返回值;cancel(mayInterruptIfRunning)
:取消任务。- 把Runnable转为CallAble:
Executors.callAble(Runnable)
;
private static void testCancel() throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(10, r -> {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
});
Future<Integer> future = executorService.submit(() -> {
TimeUnit.SECONDS.sleep(10);
System.out.println();
return 10;
});
TimeUnit.SECONDS.sleep(2);
System.out.println(future.cancel(true));
System.out.println(future.isCancelled());
System.out.println(future.isDone());
}
2. Future缺陷以及解决方案
- 缺陷:使用Future可以保证任务的异步执行;但是,只要去获取任务的结果,就会导致程序的阻塞;从而,从异步再次变为了同步。
private static void futureExecSomeTask() throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newFixedThreadPool(2);
final List<Callable<Integer>> callableList = Arrays.asList(
() -> {
TimeUnit.SECONDS.sleep(10);
System.out.println("Thread 10 finished!");
return 10;
},
() -> {
TimeUnit.SECONDS.sleep(20);
System.out.println("Thread 20 finished!");
return 20;
}
);
List<Future<Integer>> futureList = executorService.invokeAll(callableList);
for (Future<Integer> future : futureList) {
System.out.println(future.get());
}
}
- 解决方案(JDK1.7)
private static void futureDefect() throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(2);
final List<Callable<Integer>> callableList = Arrays.asList(
() -> {
TimeUnit.SECONDS.sleep(10);
System.out.println("Thread 10 finished!");
return 10;
},
() -> {
TimeUnit.SECONDS.sleep(20);
System.out.println("Thread 20 finished!");
return 20;
}
);
List<Future<Integer>> futureList = new ArrayList<>();
futureList.add(executorService.submit(callableList.get(0)));
futureList.add(executorService.submit(callableList.get(1)));
for (Future<Integer> future : futureList) {
System.out.println(future.get());
}
}
- 解决方案(jdk 1.8 CompletionService)
private static void testCompleteExecutorService() throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newFixedThreadPool(2);
final List<Callable<Integer>> callableList = Arrays.asList(
() -> {
TimeUnit.SECONDS.sleep(10);
System.out.println("Thread 10 finished!");
return 10;
},
() -> {
TimeUnit.SECONDS.sleep(20);
System.out.println("Thread 20 finished!");
return 20;
}
);
ExecutorCompletionService<Integer> completionService = new ExecutorCompletionService<>(executorService);
callableList.stream().forEach(item -> completionService.submit(item));
Future<Integer> future;
while ((future = completionService.take()) != null) {
System.out.println(future.get());
}
System.out.println("Main is finished!");
}