乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Android(Java)之多線程結(jié)果返回——Future 、FutureTask、Callable、Runnable

       波波七 2016-06-22

      Android、Java中Runnable十分常見,在開新線程時(shí),我們常用new Thread(Runnable).start() 或者線程池搭載Runnable。

      日常使用,在不需要線程返回時(shí),使用的十分順手。

      在需要線程返回時(shí),我們也有辦法搞定,比如外部變量控制流程、新增監(jiān)聽接口等。

      有了以上理由,Callable就被冷落了。

      其實(shí)Callable能讓你的實(shí)現(xiàn)以及代碼更簡(jiǎn)單。本文就是以Callable為中心來介紹的。

      一、Callable與Runnable

      為什么Runnable用的人多,而Callable用的少?

      1、Callable還沒出現(xiàn)前,大家用的都是Runnable;(Callable是JDK5出現(xiàn)的)

      2、Runnable用法更簡(jiǎn)單;

      具體的區(qū)別如下:

      1、結(jié)構(gòu)

      Callable接口是帶有泛型的,Callable<T>。該泛型T,也是Callable返回值的類型;Callable接口需要實(shí)現(xiàn)的方法為call方法;

      Runnable接口需要實(shí)現(xiàn)的方法為run方法;

      2、使用

      Callable一般配合線程池的submit方法以及FutureTask使用,Runnable一般是配合new Thread或者線程池使用;

      3、返回

      Callable有返回值,并且可以自定義返回值類型;Runnable不行;

      4、控制

      Callable配合FutureTask,可以通過Future來控制任務(wù)執(zhí)行、取消,查看任務(wù)是否完成等。Runnable也可以通過Future來實(shí)現(xiàn)以上功能,但方式不一樣。


      二、Future以及FutureTask

      Callable的價(jià)值,在Future上體現(xiàn)。

      Future是一個(gè)接口,而FutureTask是Future接口的官方唯一實(shí)現(xiàn)類。

      1、Future接口

      Future以及其實(shí)現(xiàn)類,是用于搭載Runnable或者Callable,執(zhí)行任務(wù)、控制任務(wù)并能有效返回結(jié)果。

      Future接口內(nèi)容如下(去了注釋):

      1. package java.util.concurrent;  
      2.   
      3.   
      4. public interface Future<V> {  
      5.      
      6.     boolean cancel(boolean mayInterruptIfRunning);  
      7.   
      8.     boolean isCancelled();  
      9.   
      10.     boolean isDone();  
      11.       
      12.     V get() throws InterruptedException, ExecutionException;   
      13.       
      14.     V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;  
      15.       
      16.     }  

      其中,isCancelled用于判斷是否已取消任務(wù)、isDone用于判斷是否已完成任務(wù)。

      cancel用于取消任務(wù),cancel的參數(shù)表示是否可以中斷正在執(zhí)行中的任務(wù)。參數(shù)解釋如下:

      任務(wù)未開始:無論設(shè)置參數(shù)為true還是false,都返回true;

      任務(wù)正在執(zhí)行,并未結(jié)束:參數(shù)設(shè)置為true,則返回true(成功取消),如果設(shè)置為false,則返回false(不允許中斷正在執(zhí)行的任務(wù));

      任務(wù)已結(jié)束:無論設(shè)置參數(shù)為true還是false,都返回false;

      get方法用于獲取任務(wù)執(zhí)行的結(jié)果,get方法是一個(gè)阻塞方法,會(huì)等到任務(wù)執(zhí)行完畢。

      get(long timeout,TimeUnit unit)方法也是一個(gè)阻塞方法,等待任務(wù)執(zhí)行的結(jié)果,但它只等到超時(shí)時(shí)間結(jié)束,如果任務(wù)還未執(zhí)行完成,則返回一個(gè)null。

      2、FutureTask類

      FutureTask類不止實(shí)現(xiàn)了Future接口,還實(shí)現(xiàn)了其他的接口——Runnable,如下:

      1. public class FutureTask<V> implements RunnableFuture<V>  
      1. public interface RunnableFuture<V> extends Runnable, Future<V>  
      因此,F(xiàn)utureTask其實(shí)也可以用于new Thread(FutureTask),當(dāng)然也用于線程池。

      FutureTask與Future接口相比,功能擴(kuò)張了很多。

      首先看它的構(gòu)造函數(shù):

      1. public FutureTask(Runnable runnable, V result)  
      1. public FutureTask(Callable<V> callable)  
      看到這里,我們知道通過FutureTask,你可以傳入Callable或者Runnable,而FutureTask則搭載二者。最后,F(xiàn)utureTask會(huì)將自身作為新開線程或者線程池的參數(shù)。

      FutureTask有一個(gè)很重要的方法,是Done(),用于表示該FutureTask中的任務(wù)已執(zhí)行完畢。后面會(huì)在代碼中介紹。


      三、實(shí)例解析

      有這么一個(gè)場(chǎng)景:

      你需要順序的執(zhí)行一系列任務(wù),上一個(gè)任務(wù)是下一個(gè)任務(wù)的前置。下一個(gè)任務(wù)需要根據(jù)上一個(gè)任務(wù)的結(jié)果來判斷是否執(zhí)行。如果上一個(gè)任務(wù)失敗則不再往下執(zhí)行任務(wù)。

      這些任務(wù)都是耗時(shí)的,你是在Android上執(zhí)行這些任務(wù)的。

      出現(xiàn)這個(gè)場(chǎng)景,在JDK5前,你用Runnable以及外部變量控制,是可以實(shí)現(xiàn)的。在JDK5以后,我們嘗試用Callable配合FutureTask來實(shí)現(xiàn)。(Runnable配合Future也是可以的,只是不常用)。


      根據(jù)場(chǎng)景,設(shè)計(jì)方案:

      (1)串行線程池+Callable+FutureTask

      (2)串行線程池+Runnable+FutureTask

      (3)外部變量控制——不再演示

      (4)全局監(jiān)聽——不再演示

      這里演示的是1、2兩種方案。

      這里貼上為以上場(chǎng)景寫的工具類和方法:

      1. package com.example.androidfuturecallabledemo;  
      2.   
      3. import java.util.concurrent.Callable;  
      4. import java.util.concurrent.ExecutorService;  
      5. import java.util.concurrent.Executors;  
      6. import java.util.concurrent.FutureTask;  
      7.   
      8. public class FutureThreadPool {  
      9.   
      10.     private FutureThreadPool(){}  
      11.     private volatile static FutureThreadPool futureThreadPool;  
      12.     private static ExecutorService threadExecutor;  
      13.     /**  
      14.      * 獲取線程池實(shí)例(單例模式)  
      15.      * @return  
      16.      */  
      17.     public static FutureThreadPool getInstance(){  
      18.         if(futureThreadPool==null){  
      19.             synchronized (FutureThreadPool.class) {  
      20.                 futureThreadPool=new FutureThreadPool();  
      21.                 threadExecutor=Executors.newSingleThreadExecutor();  
      22.             }  
      23.         }  
      24.         return futureThreadPool;  
      25.     }  
      26.       
      27.       
      28.     /**  
      29.      * 線程池處理Runnable(無返回值)  
      30.      * @param runnable Runnable參數(shù)  
      31.      */  
      32.     public void executeTask(Runnable runnable){  
      33.         threadExecutor.execute(runnable);  
      34.     }  
      35.       
      36.     /**  
      37.      * 線程池處理Callable<T>,F(xiàn)utureTask<T>類型有返回值  
      38.      * @param callable Callable<T>參數(shù)  
      39.      * @return FutureTask<T>  
      40.      */  
      41.     public <T> FutureTask<T> executeTask(Callable<T> callable){  
      42.         FutureTask<T> futureTask= new FutureTask<T>(callable);  
      43.         threadExecutor.submit(futureTask);  
      44.         return futureTask;  
      45.           
      46.     }  
      47.     /**  
      48.      * 線程池處理Runnable,F(xiàn)utureTask<T>類型有返回值(該方法不常用)  
      49.      * @param Runnable參數(shù)  
      50.      * @param T Runnable任務(wù)執(zhí)行完成后,返回的標(biāo)識(shí)(注意:在調(diào)用時(shí)傳入值,將在Runnable執(zhí)行完成后,原樣傳出)  
      51.      * @return FutureTask<T>  
      52.      */  
      53.     public <T> FutureTask<T> executeTask(Runnable runnable,T result){  
      54.         FutureTask<T> futureTask= new FutureTask<T>(runnable,result);  
      55.         threadExecutor.submit(futureTask);  
      56.         return futureTask;  
      57.     }  
      58.     /**  
      59.      * 線程池處理自定義SimpleFutureTask,任務(wù)結(jié)束時(shí)有onFinish事件返回提示  
      60.      * @param mFutureTask 自定義SimpleFutureTask  
      61.      */  
      62.     public  <T> FutureTask<T>  executeFutureTask(SimpleFutureTask<T> mFutureTask){  
      63.         threadExecutor.submit(mFutureTask);  
      64.         return mFutureTask;  
      65.     }  
      66.       
      67.       
      68. }  

      1. package com.example.androidfuturecallabledemo;  
      2.   
      3. import java.util.concurrent.Callable;  
      4. import java.util.concurrent.FutureTask;  
      5. /**  
      6.  * 任務(wù)結(jié)束回調(diào)onFinish的添加  
      7.  * @author zhao.yang  
      8.  *  
      9.  * @param <T>  
      10.  */  
      11. public abstract class SimpleFutureTask<T> extends FutureTask<T>{  
      12.   
      13.     public SimpleFutureTask(Callable<T> callable) {  
      14.         super(callable);  
      15.     }  
      16.   
      17.     @Override  
      18.     protected void done() {  
      19.         onFinish();  
      20.     }  
      21.       
      22.     public abstract void onFinish();  
      23.   
      24.       
      25. }  

      以上是創(chuàng)建的工具類,結(jié)合封裝了Callable/Runnable、FutureTask以及線程池,方便調(diào)用。這里特別注意executeFutureTask方法,在該方法中,重寫了done方法以及新增

      onFinish抽象方法,可以通過回調(diào)onFinish,通知調(diào)用者任務(wù)執(zhí)行結(jié)束。調(diào)用者,也可以通過FutureTask的get方法來阻塞,直到任務(wù)結(jié)束。


      最后,貼上調(diào)用代碼:

      1. package com.example.androidfuturecallabledemo;  
      2.   
      3. import java.util.concurrent.Callable;  
      4. import java.util.concurrent.ExecutionException;  
      5. import java.util.concurrent.Future;  
      6. import java.util.concurrent.FutureTask;  
      7.   
      8. import android.app.Activity;  
      9. import android.os.Bundle;  
      10. import android.view.View;  
      11. import android.view.View.OnClickListener;  
      12. import android.widget.Button;  
      13. import android.widget.TextView;  
      14.   
      15. public class MainActivity extends Activity {  
      16.   
      17.     Button btnButton;  
      18.     TextView txtTextView;  
      19.     @Override  
      20.     protected void onCreate(Bundle savedInstanceState) {  
      21.         super.onCreate(savedInstanceState);  
      22.         setContentView(R.layout.activity_main);  
      23.         btnButton=(Button)findViewById(R.id.btn);  
      24.         txtTextView=(TextView)findViewById(R.id.txt);  
      25.           
      26.         btnButton.setOnClickListener(new OnClickListener() {  
      27.               
      28.             @Override  
      29.             public void onClick(View v) {  
      30.                 try {  
      31.                     doSomeThing();  
      32.                 } catch (InterruptedException e) {  
      33.                     e.printStackTrace();  
      34.                 } catch (ExecutionException e) {  
      35.                     e.printStackTrace();  
      36.                 }  
      37.             }  
      38.         });  
      39.     }  
      40.     private int i=0;  
      41.     public void doSomeThing() throws InterruptedException, ExecutionException{  
      42.         System.out.println("1 main thread ..."+" Thread id:"+Thread.currentThread().getId());  
      43.         //Runnable  
      44.         FutureThreadPool.getInstance().executeTask(new Runnable() {  
      45.               
      46.             @Override  
      47.             public void run() {  
      48.                 try {  
      49.                     Thread.sleep(3*1000);  
      50.                     System.out.println("2 Runnable in FutureTask ..."+" Thread id:"+Thread.currentThread().getId());  
      51.                 } catch (InterruptedException e) {  
      52.                     // TODO Auto-generated catch block  
      53.                     e.printStackTrace();  
      54.                 }  
      55.                   
      56.             }  
      57.         });  
      58.       
      59.         //Callable   
      60.         Future<String> futureTask= FutureThreadPool.getInstance().executeTask(new Callable<String>() {  
      61.               
      62.             @Override  
      63.             public String call() throws Exception {  
      64.                 Thread.sleep(3*1000);  
      65.                 return "callable back return";  
      66.             }  
      67.         });  
      68.          System.out.println("3 Callable in FutureTask ... Result:"+futureTask.get()+" Thread id:"+Thread.currentThread().getId());  
      69.           
      70.        //Runnable+T result  
      71.      FutureTask<Integer> futureTask2=FutureThreadPool.getInstance().executeTask(new Runnable() {  
      72.           
      73.         @Override  
      74.         public void run() {  
      75.                  i=7;             
      76.         }  
      77.     }, 9);  
      78.        
      79.      System.out.println("4 Callable and <T> in FutureTask ... Result:"+futureTask2.get()+" Thread id:"+Thread.currentThread().getId()+" i="+i);  
      80.   
      81.           
      82.          FutureThreadPool.getInstance().executeFutureTask(new myFutrueTask(new Callable<String>() {  
      83.   
      84.             @Override  
      85.             public String call() throws Exception {  
      86.                 // TODO Auto-generated method stub  
      87.                 String resu="5 SimpleFutureTask";  
      88.                  System.out.println("5 SimpleFutureTask ... Result:"+resu+" Thread id:"+Thread.currentThread().getId());  
      89.                 return resu;  
      90.             }  
      91.         }));  
      92.     }  
      93.       
      94.     class myFutrueTask extends SimpleFutureTask<String>{  
      95.   
      96.         public myFutrueTask(Callable<String> callable) {  
      97.             super(callable);  
      98.         }  
      99.   
      100.         @Override  
      101.         public void onFinish() {  
      102.              System.out.println("6 SimpleFutureTask ...Finish");  
      103.         }  
      104.           
      105.     }  
      106.   
      107. }  

      運(yùn)行,得到的結(jié)果如下:



      注意點(diǎn)


      在代碼運(yùn)行過程中,有個(gè)地方十分需要注意,那就是FutureTask的其中一個(gè)重載方法:

      1. public FutureTask(Runnable runnable, V result)  
      在代碼的調(diào)用中,我們傳入的是一個(gè)整形i,i最初復(fù)制為0,在任務(wù)中被賦值為7,但是在參數(shù)中,我們傳入的是9。看打印出來的信息我們知道,通過get方法,我們得到的值是9,而不是其他值。

      看它在源碼中的調(diào)用:

      1. public FutureTask(Runnable runnable, V result) {  
      2.       this.callable = Executors.callable(runnable, result);  
      3.       this.state = NEW;       // ensure visibility of callable  
      4.   }  

      1. public static <T> Callable<T> callable(Runnable task, T result) {  
      2.        if (task == null)  
      3.            throw new NullPointerException();  
      4.        return new RunnableAdapter<T>(task, result);  
      5.    }  

      1. static final class RunnableAdapter<T> implements Callable<T> {  
      2.       final Runnable task;  
      3.       final T result;  
      4.       RunnableAdapter(Runnable task, T result) {  
      5.           this.task = task;  
      6.           this.result = result;  
      7.       }  
      8.       public T call() {  
      9.           task.run();  
      10.           return result;  
      11.       }  
      12.   }  

      在第三段代碼中,你就懂的,這個(gè)T result,你傳入什么,在任務(wù)結(jié)束時(shí),就傳回原值。

      四、源碼

      源碼地址:http://download.csdn.net/detail/yangzhaomuma/9554877




        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多