Futrue初探
Runnable和Callable的区别?
Runnable是一个无返回值,并且不能checked Exception的任务定义,java中之所以这样实现是因为执行Runnable方法是调用的Threa.run()方法,不是当前线程进行执行,所以就算抛出异常我们也无法捕捉到;
Callable方法定义的是一个有返回值并且可抛出异常的方法,底层采用的是submit()方法,返回的是Futrue
Futrue的主要功能?
Futrue接口
public interface Future<V> {
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit)throws InterruptedException, ExecutionException, TimeoutException;
}
- 获取返回值
public static void main(String[] args) throws ExecutionException, InterruptedException {
List<Future<String>> futures = new ArrayList<Future<String>>();
for (int i = 0; i < 100; i++) {
Future<String> future = threadPool.submit(() -> Thread.currentThread().getName());
futures.add(future);
}
futures.forEach(e -> {
System.out.println(e.get());
});
threadPool.shutdown();
}
- checked Exception
- 取消任务
- 判断是否执行完毕
Futrue的注意点?
- **Futrue.get()**是一个阻塞方法,在遍历Futrue时注意该方法是阻塞的去获取不同线程的返回值的,这里可以采用get(timeout)的方式
- Futrue本身并没有产生新的线程,这里是利用Threa或者线程池的技术来执行任务的
演示代码
public static void main(String[] args) throws InterruptedException, TimeoutException, ExecutionException {
Set<Integer> set = Collections.synchronizedSet(Sets.newHashSet());
List<CompletableFuture<Void>> tasks = Lists.newArrayList();
for (int i = 0; i < 3; i++) {
CompletableFuture<Void> task = CompletableFuture.runAsync(() ->{
double val = Math.random()*10000;
System.out.println(Thread.currentThread().getName() + " execute...val:" + val);
set.add((int) val);
});
tasks.add(task);
}
CompletableFuture<Void> task0 = tasks.get(0);
CompletableFuture<Void> task1 = tasks.get(1);
CompletableFuture<Void> task2 = tasks.get(2);
CompletableFuture<Void> task = CompletableFuture.allOf(task0,task1,task2);
task.get(3,TimeUnit.SECONDS);
set.stream().forEach(e ->System.out.println(e));
}
- 通过Collections.synchronizedSet获取到并发安全的set,利用Completable.runAsync执行任务并将结果写入set中,Future队列进行等待,定时等待结束,获取结果。