一、Runnable和Callable< V >源码

先回顾一下Runnable和Callable< V >源码吧;

//Runnable 源码
@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

//Callable<V>源码
public interface Callable<V> {
    //返回V对象
    V call() throws Exception;
}
源码中得出基本信息:
1.Runnable和Callable< V >的源码真的是少到极致了。这应该是遵循设计原则中的接口隔离原则吧,二者都是定义了一个标准的函数,具体逻则是由其子类实现;
2.Runnable 接口中声明返回值为void的run方法;所以Runnable开启的线程犹如脱缰骏马任其驰骋难以掌控,结果导致两个问题:1).无法直接获取到线程执行执行的结果,需要借助一个全局变量;2)不能直接捕获线程执行中的异常;
  • 正是由于Runnable的“无法无天”难以控制,所以Java中的Callable< v >应用而生;
3.在Callable< v >源码可以看到与Runnable不同的是Callable< v >接口引入泛型V,在声明的call函数返回V 并且抛出Exception真的专门应对Runnable中的没有返回值和捕获异常的个问题的。
二、Callable< V >的异步管理类Future< V >
Future< V >接口

正如上面说的与Runable相比Callable< v >开发了更多的管理操作的权限,但是Callable中只有call函数,所以Java中提供了一个Future类用于管理Callable。然而Future< V >也同样是一个接口:

//Future<V>源码
public interface Future<V> {
   //取消Task线程:参数 如果是线程正在执行,是否中断;返回中断结果:ture 中断成功;false 中断失败
    boolean cancel(boolean mayInterruptIfRunning);

    //判断该Task是否已近取消
    boolean isCancelled();

   //判断该Task是否完成
    boolean isDone();

    //获取该线程返回的结果,如果线程为执行完阻塞,等待执行完再返回
    V get() throws InterruptedException, ExecutionException;

    //获取该线程返回的结果,设置超时,超时抛出Exception
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}
Future< V >定义标准函数的接口,基本功能:
  • 1.判断当前任务是否完成
  • 2.中断当前任务,判断是否已近中断
  • 3.阻塞或者设置超时,获取异步Task结果,
Future< V >的实现类FutureTask

在源码中FutureTask实现RunnableFuture< V > 接口,然而RunnableFuture< V > 同样是实现了Runnable和Future< V > 接口;按照Java的继承原则和特征, 因此FutureTask实际中实现了Future< V >接口,同时也具备了Future的所用基本功能;

三、开启Callable< V >异步线程的基本方式

首先在Java中开启异步线程都应该会想到线程池吧,Callable同样可以借助线程池进行开启关闭,其次Callable< V >异步线程的开启肯定是要借助它的实行类FutureTask,上文中已经提到的FutureTask是implements了Runnable,所以FutureTask同样可以借助Thread类包装直接执行;
1.线程池中的在ExecutorService中定义了< T > Future< T > submit(Callable< T > task)函数就是用于开始执行Callable< V >任务滴;
ExecutorService开启Callable的demo代码:

public static void main(String[] args) {
        //线程池submit开启多线程
try {
             CallableMThread mThread = new CallableMThread();
            ExecutorService threadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
            Future<String> submit = threadPool.submit(mThread);
            String resualt = submit.get();
            System.out.println(resualt);
            threadPool.shutdown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

}
//内部类的实现Callable<V>开启新线程方式
 class CallableMThread implements Callable<String> {

        @Override
        public String call() throws Exception {
            // TO DO
            return "ThreadID :" + Thread.currentThread().getId() + " ThreadRandom :" + (Math.random() * 1000);
        }
    }

2.借助Thread包装开启Callable< V >异步线程

实现Callable< T >接口多线程例子

public static void main(String[] args) {
     try {
             //FutureTask启动线程
            CallableMThread mThread = new CallableMThread();
            FutureTask<String> task = new FutureTask<String>(mThread);
             new Thread(task).start();
            //返回的String结果
            String resualt = task.get();
            System.out.println(resualt);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }


}
//内部类的实现Callable<V>开启新线程方式
 class CallableMThread implements Callable<String> {

        @Override
        public String call() throws Exception {
            // TO DO
            return "ThreadID :" + Thread.currentThread().getId() + " ThreadRandom :" + (Math.random() * 1000);
        }
    }
}

3.Callable< V >开启一组线程;
实际开发中有些特殊场景需求是最短时间内完协作成几个Task,最后汇总结果呈现给用户;这一类需求往往是十分重要的交互界面的需求,所以咋能不来个demo呢

public static void main(String[] args) {
    try {
        CallableMThread mThread = new CallableMThread();
        int coreSize = Runtime.getRuntime().availableProcessors();
        //创建一个线程
        ExecutorService executor = Executors.newFixedThreadPool(coreSize);
        //创建多个有返回值的任务
        List<Future> list = new LinkedList<Future>();
        for (int i = 0; i < coreSize; i++) {
            FutureTask task = new FutureTask(mThread);
            //执行任务并获取future
            Future future = executor.submit(task);
            list.add(future);
        }
            //关闭线程池
            executor.shutdown();
            //获取并发任务结果
            for (Future mFuture : list) {
                //Future对象获取返回值
                String resualt = mFuture.get().toString();
                //输出结果
                System.out.printf(resualt);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

}
//内部类的实现Callable<V>开启新线程方式
 class CallableMThread implements Callable<String> {

        @Override
        public String call() throws Exception {
            // TO DO
            return "ThreadID :" + Thread.currentThread().getId() + " ThreadRandom :" + (Math.random() * 1000);
        }
    }