java.util.concurrent.Callable

来源:互联网 发布:js prompt没弹出来 编辑:程序博客网 时间:2024/06/06 07:19

1. java.util.concurrent.Callable

1.1 概述

Callable是一个返回一个结果或者抛出一个异常的任务接口,其中定义了一个call()方法用来实现具体的任务逻辑。
Callable接口与Runnable接口相似,两者都是为了实现另外一个线程实例而设计的。

1.1.1 与Runnable接口的不同之处

  • Runnable接口无法返回具体任务的结果,Callable接口可以返回具体任务的结果。因此,Callable可以处理较为复杂的场景。
  • 发生异常时,Runnable不会抛出异常,Callable接口会抛出异常
  • Runnable可以通过调用start()方法来启用线程,Callable接口则需要配合线程池的submit()方法来启动

1.2 Callable API设计

如图:
这里写图片描述
call()方法是用来处理具体的业务场景,并将处理结果返回去。如果出现异常,则抛出来。

1.3 获取Callable接口call()方法返回值方式

1.3.1 采用Future方式获取

1.3.1.1 Future概述

Future是用来获取异步计算的结果的。Future提供了一些方法来获取和操作执行具体任务的过程状态。

1.3.1.2 Future API设计

这里写图片描述
- boolean cancel(boolean mayInterruptIfRunning)
试图取消正在执行的任务。mayInterruptIfRunning表示当前线程如果需要被中断时设置为true,否则,按照线程正常执行,直到完成
- boolean isCancelled()
如果当前线程在正常完成之前被取消的话返回true
- boolean isDone()
当前任务完成时返回true。完成指当前任务在被正常终止、异常、取消等所有的这些情况下均返回true.
- V get()
如果必要的话,等待当前任务执行的结果,并返回。这个方法会造成线程阻塞
- V get(long timeout, TimeUnit unit) throws InterruptedException,ExecutionException, TimeoutException
如果必要的话,在给定的时间内等待当前任务的执行结果,如果有结果,就返回。

1.3.2 采用FutureTask方式获取

1.3.2.1 FutureTask 概述

FutureTask这个类提供了一个基于Future接口的实现,可以使用方法来开始或者取消一个计算(任务),查看计算是否已经完成,并取回计算的结果。计算结果仅可以在计算完成时被取到,如果计算还没有完成那么使用get方法将会被阻塞。一旦计算已经完成,那么计算不能重新开始或者取消。除非计算采用的是runAndReset()方法来使用的。
FutureTask 可以用来包装Runnable对象和Callable对象,一个FutureTask对象可以提交到线程池中去执行。

1.3.2.2 FutureTask API 设计

这里写图片描述
通过上UML图可以看出,FutureTask这个类RunnableFuture这个接口实现Future接口和Runnable接口,并提供了两个构造器来包装Runnable对象和Callable对象

1.4 代码示例:

示例中包括Future方式和FutureTask方式

public class CallableFutureDemo {    public static void main(String[] args) throws ExecutionException, InterruptedException {        // 声明一个线程对象        ExecutorService executorService = Executors.newSingleThreadExecutor();        Task task = new Task(); // Callable对象        Object obj = null; // 用于接收callable接口call方法的返回值        /**         * Callable + Future 实现获取线程任务的返回值         */        Future future = executorService.submit(task);        try {            obj = future.get();        } catch (InterruptedException e) {            e.printStackTrace();        } catch (ExecutionException e) {            e.printStackTrace();        }        System.out.println("Callable + Future 实现获取线程任务的返回值;" + obj);        /**         * 通过FutureTask获取线程任务的返回值         */        FutureTask futureTask = new FutureTask(task);        executorService.submit(futureTask);        obj = futureTask.get();        System.out.println("通过FutureTask获取线程任务的返回值: " + obj);        // 关闭线程池        executorService.shutdown();    }    /**     * 新建Task类并实现Callable接口,重写call()方法。     */    static class Task implements Callable {        @Override        public Object call() throws Exception {            System.out.println("进入子线程。。。。。。。。");            /**             * 简单的计算,将计算结果返回             */            int count = 0;            int length = new Random().nextInt(10);            System.out.println("共循环" + length + "次");            for (int i = 0 ; i < length ; i ++) {                count += i;                System.out.println("count第" + (i + 1) + "次运算的值:" + count);            }            return count;        }    }}

参考链接:https://docs.oracle.com/javase/8/docs/api/
http://blog.csdn.net/javazejian/article/details/50896505
http://blog.csdn.net/zhoushumin157016/article/details/51995818
http://www.cnblogs.com/MOBIN/p/6185387.html

源代码链接:https://github.com/myNameIssls/javase-study/blob/master/javase-multithreading/src/main/java/cn/tyrone/javase/concurrent/CallableFutureDemo.java

原创粉丝点击