Futrue初探


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的注意点?

  1. **Futrue.get()**是一个阻塞方法,在遍历Futrue时注意该方法是阻塞的去获取不同线程的返回值的,这里可以采用get(timeout)的方式
  2. 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队列进行等待,定时等待结束,获取结果。

  TOC