多線程編程之 Runnable、Callable、Future、FutureTask和AsyncTask源碼分析

上一篇對線程的基礎(chǔ)概念和如何使用做了些基本的介紹 本篇將繼續(xù)對線程深入的學(xué)習(xí)
多線程編程基礎(chǔ)之 wait()、notify()、sleep()、join()、yield()、synchronized關(guān)鍵字Lock鎖等

首先了解下多線程中Runnable、Callable、Future、FutureTask
  1. Runnable和Callable都是接口 區(qū)別在于回調(diào)函數(shù)是否有返回值 單獨(dú)來講他們跟線程是一點(diǎn)關(guān)系都沒有的(就是一個接口嘛)
public interface Runnable {
       public abstract void run();
}
public interface Callable<V> {
    V call() throws Exception;
}
  1. Future、FutureTask 其中Future是一個接口 FutureTask是其實(shí)現(xiàn)類 同時也實(shí)現(xiàn)了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與線程的關(guān)系

通過上面源碼確實(shí)沒有看出他們與線程的關(guān)系 是如何使用在線程中的呢?

  1. Runnable在線程中的使用

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


    通過源碼可以看出 Thread實(shí)現(xiàn)了Runnable接口 在成員變量target不為空的時候 執(zhí)行target的run()函數(shù) 為空就執(zhí)行實(shí)現(xiàn)接口Runnable的回調(diào)函數(shù)run()
    同時要注意的是只有Thread在調(diào)用start()函數(shù)后 run()函數(shù)才真正的在分線程中執(zhí)行 否則在start()調(diào)用前執(zhí)行run()函數(shù)那就不是在分線程中執(zhí)行了(這是一般情況下來講,拋開分線程中創(chuàng)建Thread執(zhí)行Run()不說)

  2. Callable在線程中的使用:
    一般情況下Callable是無法直接在線程中使用的 需要通過FutureTask進(jìn)行包裝一下 上面源碼也看到FutureTask是繼承了RunnableFuture接口的(目的就是將其轉(zhuǎn)換為Runnable傳入Thread(Runnable)構(gòu)造函數(shù)去分線程執(zhí)行call()函數(shù)) 其作用有可以在線程中獲取call()的返回值 取消異步任務(wù) 等其他相關(guān)操作

    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){
             //異步任務(wù)執(zhí)行完成,回調(diào)
             @Override
             protected void done() {
                 try {
                     //get()獲取異步任務(wù)返回值
                     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**在線程執(zhí)行完成后 會回調(diào)**done()** 調(diào)用**get()**函數(shù)可以在線程執(zhí)行完成后獲取**Callable**接口回調(diào)函數(shù)**call()**的返回值 如圖:
![thread04](http://upload-images.jianshu.io/upload_images/2158254-5aaf7c2c5d121572.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

######AsyncTask源碼分析 

1. 在Android中可以將耗時的操作交由**AsyncTask**去操作 上面對Runnable、Callable、Future、FutureTask做了比較詳細(xì)的分析和使用 其實(shí)AsyncTask就是采用的通過FutureTask能獲取Callable接口call()函數(shù)返回值的思路去實(shí)現(xiàn)的 

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

![](http://upload-images.jianshu.io/upload_images/2158254-eda4a72d72b2d362.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

上圖只是對**AsyncTask**執(zhí)行流程圖做了粗略的分析 其中doInBackground()函數(shù)是在Callable的call()里面執(zhí)行的 并通過FutureTask包裝為Runnable交由分線程去執(zhí)行 再通過FutureTask的get()函數(shù)獲取doInBackground()的返回值 通過InternalHandler發(fā)送消息到主線程執(zhí)行AsyncTask的onPostExecute(result)函數(shù)方法
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容