JAVA学习笔记(三)-并发编程 Callable Future CompleableFuture

Runnable 是一个接口,里面只声明了一个方法run();返回值为void所以无法拿到执行完的结果。只能通过共享变量或者线程通信来搞定。

//函数式接口注解
@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

Callable同样也只是一个接口,只声明了一个方法call(),可以看出来他是一个泛型接口,call方法返回结果类型V。

@FunctionalInterface
public interface Callable {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}

Future就是对具体的Runable或者Callable任务的执行结果进行取消,查询是否完成,获取结果。

public interface Future {
    //取消任务,成功返回true,失败 返回false, 参数mayInterruptIfRunning表示是否允许取消正在运行的任务,
    boolean cancel(boolean mayInterruptIfRunning);
    //返回任务是否取消成功
    boolean isCancelled();

    //返回任务是否完成
    boolean isDone();

    //返回执行结果,若任务没有执行完,则会阻塞等待执行结果返回
    V get() throws InterruptedException, ExecutionException;

    //返回执行结果,若在指定时间内没有返回则直接返回null
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

FutureTask实现了RunnableFuture接口,RunableFuture接口继承了Runable和Future接口,所以他既可以被线程执行,也可以作为Future得到Callable的返回值。

public class FutureTask<V> implements RunnableFuture<V>;


public interface RunnableFuture<V> extends Runnable, Future<V> {
    /**
     * Sets this Future to the result of its computation
     * unless it has been cancelled.
     */
    void run();
}

Callabel Future实例

//定义一个Callabel实现类
public class CallabeTask implements Callable {

    @Override
    public Integer  call() throws Exception {
        System.out.println("调用CallableTask");
        Thread.sleep(3000);
        System.out.println("辅线程计算完毕");  
        return 1;
    }

}
//测试程序
public class test {
    public static void main(String[] args) throws InterruptedException, ExecutionException{
        ExecutorService excutor=Executors.newCachedThreadPool();
        CallabeTask task=new CallabeTask();
        Future result=excutor.submit(task);
        excutor.shutdown();
        System.out.println("主线程执行");
        System.out.println("辅线程结果"+result.get());
    }
}

执行结果:调用CallableTask
主线程执行
辅线程计算完毕
辅线程结果1
Callable 和FutureTask

public class test {
    public static void main(String[] args) throws InterruptedException, ExecutionException{
ExecutorService excutor=Executors.newCachedThreadPool();
        CallabeTask task=new CallabeTask();
        FutureTask futureTask=new FutureTask(task);
        excutor.submit(futureTask);
        excutor.shutdown();
        System.out.println("主线程执行");
        System.out.println("辅线程结果"+futureTask.get());
        }
}

执行结果:
主线程执行
调用CallableTask
辅线程计算完毕
辅线程结果1
CompletableFutures是java8中新增加的一个类,主要用来处理异步。

public class test {
    public static void main(String[] args) throws InterruptedException, ExecutionException{
    //线程池
    ExecutorService excutor=Executors.newFixedThreadPool(5);
    //生成CompletableFuture实例,并指定任务执行逻辑
        CompletableFuture resultFuture=CompletableFuture.supplyAsync(()->{

            System.out.println("completableFuture 1 running");
            try {
                Thread.sleep(3000);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("completableFuture 1 complete");

            return "hello completablefuture";
        },excutor);
        System.out.println(" main thread complete");
//调用Future的get()方法获取执行结果。
        System.out.println(resultFuture.get());
    }
    }
}

CompletableFuture不但可以调用get()方法获取执行结果,也可以使用回调函数来得到处理结果。

ExecutorService excutor=Executors.newFixedThreadPool(5);
        CompletableFuture resultFuture=CompletableFuture.supplyAsync(()->{

            System.out.println("completableFuture 1 running");
            try {
                Thread.sleep(3000);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("completableFuture 1 complete");

            return "hello completablefuture";
        },excutor);
        System.out.println(" main thread complete");
        //回调获取执行结果  thenAccept使用同一线程执行任务,并获取结果,thenAcceptAsync使用不同线程
        resultFuture.thenAcceptAsync((m)->{
            System.out.println(m);
            System.out.println("Get Result by Back Function ");
        });

    }

CompletableFuture可以通过completeExceptionally 函数来发出异常通知,同时我们也可以显示声明异常处理

ExecutorService excutor=Executors.newFixedThreadPool(5);
        CompletableFuture resultFuture=CompletableFuture.supplyAsync(()->{

            System.out.println("completableFuture 1 running");
            try {
                Thread.sleep(3000);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("completableFuture 1 complete");

            return "hello completablefuture";
        },excutor);
        System.out.println(" main thread complete");
        resultFuture.thenAcceptAsync((m)->{
            System.out.println(m);
            System.out.println("thenaccept running");
            //显示声明异常处理
        }).exceptionally((t)->{
            System.out.println("异常处理开始");
            System.out.println(t.getMessage());
            return null;
        });
        //发出异常通知
        resultFuture.completeExceptionally(new Exception("异常"));
        System.out.println(resultFuture.get());

thenApply方法可以把多个future组合在一起。

ExecutorService excutor=Executors.newFixedThreadPool(5);
        CompletableFuture resultFuture=CompletableFuture.supplyAsync(()->{

            System.out.println("resultFuture"+Thread.currentThread().getName());

            System.out.println("resultFuture");
            return "hello result1";
        },excutor);
        CompletableFuture<Integer> resultFuture1=resultFuture.thenApplyAsync((t)->{
            System.out.println("resultFuture1"+Thread.currentThread().getName());
            System.out.println("resultFuture1");
            return t.length();
        },excutor);
        CompletableFuture<Double> resultFuture2=resultFuture1.thenApplyAsync(r->{
            System.out.println("resultFuture2"+Thread.currentThread().getName());
            return r*2.0;},excutor);
        System.out.println(resultFuture2.get());

CompletableFuture还有许多方法,来满足不同的需求场景,具体的方法 还需要使用到的时候在来进行具体分析。
CompletableFuture背后也依靠Fork/join框架(还未深入了解),来实现异步与并发。

你可能感兴趣的:(JDK,java,并发,Future)