1.Runnable
 (1).缺陷
- 没有返回值
- 不能抛出一个检查异常
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
(2).解决方案Callable
@FunctionalInterface
public interface Callable<V> {
V call() throws Exception;
}
2.Future
 (1).作用
 Future是一个存储器,它存储了Callable这个任务的执行结果,而这个任务的执行时间无法提前确定,取决于call()方法的执行情况。
(2).isDone()
 判断线程是否执行完毕,但并不能保证任务是否成功被执行。
(3).get()
 get()方法的行为取决于Callable任务的状态,该状态有以下5种情况。
- 任务正常完成
 get()方法会立刻获取任务的执行结果。
public class OneFuture {
    public static void main(String[] args) {
        ExecutorService service = Executors.newFixedThreadPool(10);
        Future<Integer> future = service.submit(new CallableTask());
        try {
            System.out.println(future.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        service.shutdown();
    }
    static class CallableTask implements Callable<Integer> {
        @Override
        public Integer call() throws Exception {
            Thread.sleep(3000);
            return new Random().nextInt();
        }
    }
}public class MultiFutures {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService service = Executors.newFixedThreadPool(20);
        ArrayList<Future> futures = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            Future<Integer> future = service.submit(new CallableTask());
            futures.add(future);
        }
        Thread.sleep(5000);
        for (int i = 0; i < 20; i++) {
            Future<Integer> future = futures.get(i);
            try {
                Integer integer = future.get();
                System.out.println(integer);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    }
    static class CallableTask implements Callable<Integer> {
        @Override
        public Integer call() throws Exception {
            Thread.sleep(3000);
            return new Random().nextInt();
        }
    }
}- 任务尚未完成()
 get()方法会阻塞,直到任务完成。
- 任务执行过程中抛出Exception
 get()方法会抛出ExecutionException。
public class GetException {
    public static void main(String[] args) {
        ExecutorService service = Executors.newFixedThreadPool(20);
        Future<Integer> future = service.submit(new CallableTask());
        try {
            future.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
            System.out.println("InterruptedException异常");
        } catch (ExecutionException e) {
            e.printStackTrace();
            System.out.println("ExecutionException异常");
        }
    }
    static class CallableTask implements Callable<Integer> {
        @Override
        public Integer call() {
            throw new IllegalArgumentException("Callable抛出异常");
        }
    }
}public class GetException {
    public static void main(String[] args) {
        ExecutorService service = Executors.newFixedThreadPool(20);
        Future<Integer> future = service.submit(new CallableTask());
        try {
            //for循环为了演示抛出Exception的时机:并不是说一产生异常就抛出,直到我们get执行时,才会抛出。
            for (int i = 0; i < 5; i++) {
                System.out.println(i);
                Thread.sleep(500);
            }
            System.out.println(future.isDone());
            future.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
            System.out.println("InterruptedException异常");
        } catch (ExecutionException e) {
            e.printStackTrace();
            System.out.println("ExecutionException异常");
        }
    }
    static class CallableTask implements Callable<Integer> {
        @Override
        public Integer call() throws Exception {
            throw new IllegalArgumentException("Callable抛出异常");
        }
    }
}- 任务被取消
 get方法会抛出CancellationException。
- 任务超时
 get()方法有一个重载方法,是传入一个延时时间的,如果在参数时间内没有获得结果,get()方法就会抛出TimeoutException。超时不需要时,要通知任务,取消任务。
(4).cancel()
 取消任务的执行。
public class Timeout {
    private static final Ad DEFAULT_AD = new Ad("无网络时候的默认广告");
    private static final ExecutorService executorService = Executors.newFixedThreadPool(10);
    static class Ad {
        String name;
        public Ad(String name) {
            this.name = name;
        }
        @Override
        public String toString() {
            return "Ad{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }
    
    static class FetchAdTask implements Callable<Ad> {
        @Override
        public Ad call() throws Exception {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                System.out.println("sleep期间被中断了");
                return new Ad("被中断时候的默认广告");
            }
            return new Ad("旅游订票哪家强?找某程!");
        }
    }
    public void printAd() {
        Future<Ad> future = executorService.submit(new FetchAdTask());
        Ad ad;
        try {
            ad = future.get(2000, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            ad = new Ad("被中断时候的默认广告");
        } catch (ExecutionException e) {
            ad = new Ad("异常时候的默认广告");
        } catch (TimeoutException e) {
            ad = new Ad("超时时候的默认广告");
            System.out.println("超时,未获取到广告");
            //传入true和false的区别,代表是否中断正在执行的任务
            boolean cancel = future.cancel(true);
            System.out.println("cancel的结果:" + cancel);
        }
        executorService.shutdown();
        System.out.println(ad);
    }
    public static void main(String[] args) {
        Timeout timeout = new Timeout();
        timeout.printAd();
    }
}(5).isCanceled()
 判断任务是否被取消。
3.FutureTask
 (1).FutureTask家族成员

public class FutureTaskDemo {
    public static void main(String[] args) {
        Task task = new Task();
        FutureTask<Integer> integerFutureTask = new FutureTask<>(task);
        ExecutorService service = Executors.newCachedThreadPool();
        service.submit(integerFutureTask);
        try {
            System.out.println("task运行结果:" + integerFutureTask.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}
class Task implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        System.out.println("子线程正在计算");
        Thread.sleep(3000);
        int sum = 0;
        for (int i = 0; i < 100; i++) {
            sum += i;
        }
        return sum;
    }
}4.CompletableFuture
 如果有多个任务,有的任务执行慢,有的任务执行慢,就可以使用CompletableFuture,某个任务先执行完就可以先获取结果。
 CompletableFuture实现了Future接口,可以当作Future使用。









