美文网首页多线程Android知识Android开发
多线程编程之 Runnable、Callable、Future、

多线程编程之 Runnable、Callable、Future、

作者: 明朗__ | 来源:发表于2017-04-16 15:04 被阅读343次

    上一篇对线程的基础概念和如何使用做了些基本的介绍 本篇将继续对线程深入的学习
    多线程编程基础之 wait()、notify()、sleep()、join()、yield()、synchronized关键字Lock锁等

    首先了解下多线程中Runnable、Callable、Future、FutureTask
    1. Runnable和Callable都是接口 区别在于回调函数是否有返回值 单独来讲他们跟线程是一点关系都没有的(就是一个接口嘛)
    public interface Runnable {
           public abstract void run();
    }
    
    public interface Callable<V> {
        V call() throws Exception;
    }
    
    1. Future、FutureTask 其中Future是一个接口 FutureTask是其实现类 同时也实现了Runnable接口
    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 interface RunnableFuture<V> extends Runnable, Future<V> {
       void run();
    }
    
    public class FutureTask<V> implements RunnableFuture<V> {......}
    
    Runnable、Callable、Future、FutureTask与线程的关系

    通过上面源码确实没有看出他们与线程的关系 是如何使用在线程中的呢?

    1. Runnable在线程中的使用

      new Thread(new Runnable(){run().....}).start();


      通过源码可以看出 Thread实现了Runnable接口 在成员变量target不为空的时候 执行target的run()函数 为空就执行实现接口Runnable的回调函数run()
      同时要注意的是只有Thread在调用start()函数后 run()函数才真正的在分线程中执行 否则在start()调用前执行run()函数那就不是在分线程中执行了(这是一般情况下来讲,抛开分线程中创建Thread执行Run()不说)

    2. Callable在线程中的使用:
      一般情况下Callable是无法直接在线程中使用的 需要通过FutureTask进行包装一下 上面源码也看到FutureTask是继承了RunnableFuture接口的(目的就是将其转换为Runnable传入Thread(Runnable)构造函数去分线程执行call()函数) 其作用有可以在线程中获取call()的返回值 取消异步任务 等其他相关操作

      static class Task implements Callable<Integer> {
           @Override
           public Integer call() throws Exception {
               int i=0;
               for(;i<5;i++){
                   System.out.println("线程:"+Thread.currentThread().getName()+"  i="+i);
                   Thread.sleep(500);
               }
               return i;
           }
       }
      
       public static void main(String[] args) throws Exception {
           Task task = new Task();
           FutureTask futureTask=new FutureTask<Integer>(task){
               //异步任务执行完成,回调
               @Override
               protected void done() {
                   try {
                       //get()获取异步任务返回值
                       System.out.println("Callable返回值:"+get());
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   } catch (ExecutionException e) {
                       e.printStackTrace();
                   }
               }
           };
           new Thread(futureTask).start();
           }
      
      线程:Thread-0  i=0
      

    线程:Thread-0 i=1
    线程:Thread-0 i=2
    线程:Thread-0 i=3
    线程:Thread-0 i=4
    Callable返回值:5

    **FutureTask**在线程执行完成后 会回调**done()** 调用**get()**函数可以在线程执行完成后获取**Callable**接口回调函数**call()**的返回值 如图:
    ![thread04](https://img.haomeiwen.com/i2158254/5aaf7c2c5d121572.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    ######AsyncTask源码分析 
    
    1. 在Android中可以将耗时的操作交由**AsyncTask**去操作 上面对Runnable、Callable、Future、FutureTask做了比较详细的分析和使用 其实AsyncTask就是采用的通过FutureTask能获取Callable接口call()函数返回值的思路去实现的 
    

    new AsyncTask<Void,Void,Void>(){
    @Override
    protected void onPreExecute() {
    }
    //分线程中执行
    @Override
    protected Void doInBackground(Void... params) {
    return null;
    }
    @Override
    protected void onPostExecute(Void aVoid) {
    }
    @Override
    protected void onProgressUpdate(Void... values) {
    }
    }.execute();

    ![](https://img.haomeiwen.com/i2158254/eda4a72d72b2d362.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    上图只是对**AsyncTask**执行流程图做了粗略的分析 其中doInBackground()函数是在Callable的call()里面执行的 并通过FutureTask包装为Runnable交由分线程去执行 再通过FutureTask的get()函数获取doInBackground()的返回值 通过InternalHandler发送消息到主线程执行AsyncTask的onPostExecute(result)函数方法

    相关文章

      网友评论

        本文标题:多线程编程之 Runnable、Callable、Future、

        本文链接:https://www.haomeiwen.com/subject/ooyaattx.html