<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      【轉】-多線程之Callable

      Java并發編程:Callable、Future和FutureTask

      該博客轉載自?Matrix海 子??Java并發編程:Callable、Future和FutureTask

      在前面的文章中我們講述了創建線程的2種方式,一種是直接繼承Thread,另外一種就是實現Runnable接口。

      這2種方式都有一個缺陷就是:在執行完任務之后無法獲取執行結果。

      如果需要獲取執行結果,就必須通過共享變量或者使用線程通信的方式來達到效果,這樣使用起來就比較麻煩。

      而自從Java 1.5開始,就提供了Callable和Future,通過它們可以在任務執行完畢之后得到任務執行結果。

      今天我們就來討論一下Callable、Future和FutureTask三個類的使用方法。以下是本文的目錄大綱:

      一.Callable與Runnable

      二.Future

      三.FutureTask

      四.使用示例

      一.Callable與Runnable

      先說一下java.lang.Runnable吧,它是一個接口,在它里面只聲明了一個run()方法:

      public interface Runnable {
          public abstract void run();
      }
      

      由于run()方法返回值為void類型,所以在執行完任務之后無法返回任何結果。

      Callable位于java.util.concurrent包下,它也是一個接口,在它里面也只聲明了一個方法,只不過這個方法叫做call():

      public interface Callable<V> {
          /**
           * Computes a result, or throws an exception if unable to do so.
           *
           * @return computed result
           * @throws Exception if unable to compute a result
           */
          V call() throws Exception;
      }
      

      可以看到,這是一個泛型接口,call()函數返回的類型就是傳遞進來的V類型。

      那么怎么使用Callable呢?一般情況下是配合ExecutorService來使用的,在ExecutorService接口中聲明了若干個submit方法的重載版本:

      <T> Future<T> submit(Callable<T> task);
      <T> Future<T> submit(Runnable task, T result);
      Future<?> submit(Runnable task);
      

      第一個submit方法里面的參數類型就是Callable。

      暫時只需要知道Callable一般是和ExecutorService配合來使用的,具體的使用方法講在后面講述。

      一般情況下我們使用第一個submit方法和第三個submit方法,第二個submit方法很少使用。

      二.Future

      Future就是對于具體的Runnable或者Callable任務的執行結果進行取消、查詢是否完成、獲取結果。必要時可以通過get方法獲取執行結果,該方法會阻塞直到任務返回結果。

      Future類位于java.util.concurrent包下,它是一個接口:

      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;
      }
      

      在Future接口中聲明了5個方法,下面依次解釋每個方法的作用:

      • cancel方法用來取消任務,如果取消任務成功則返回true,如果取消任務失敗則返回false。參數mayInterruptIfRunning表示是否允許取消正在執行卻沒有執行完畢的任務,如果設置true,則表示可以取消正在執行過程中的任務。如果任務已經完成,則無論mayInterruptIfRunning為true還是false,此方法肯定返回false,即如果取消已經完成的任務會返回false;如果任務正在執行,若mayInterruptIfRunning設置為true,則返回true,若mayInterruptIfRunning設置為false,則返回false;如果任務還沒有執行,則無論mayInterruptIfRunning為true還是false,肯定返回true。
      • isCancelled方法表示任務是否被取消成功,如果在任務正常完成前被取消成功,則返回 true。
      • isDone方法表示任務是否已經完成,若任務完成,則返回true;
      • get()方法用來獲取執行結果,這個方法會產生阻塞,會一直等到任務執行完畢才返回;
      • get(long timeout, TimeUnit unit)用來獲取執行結果,如果在指定時間內,還沒獲取到結果,就直接返回null。

      也就是說Future提供了三種功能:

      1. 判斷任務是否完成;
      2. 能夠中斷任務;
      3. 能夠獲取任務執行結果。

      因為Future只是一個接口,所以是無法直接用來創建對象使用的,因此就有了下面的FutureTask。

      三.FutureTask

      我們先來看一下FutureTask的實現:

      public class FutureTask<V> implements RunnableFuture<V>
      

      FutureTask類實現了RunnableFuture接口,我們看一下RunnableFuture接口的實現:

      public interface RunnableFuture<V> extends Runnable, Future<V> {
          void run();
      }
      

      可以看出RunnableFuture繼承了Runnable接口和Future接口,而FutureTask實現了RunnableFuture接口。所以它既可以作為Runnable被線程執行,又可以作為Future得到Callable的返回值。

      FutureTask提供了2個構造器:

      public FutureTask(Callable<V> callable) {
      }
      public FutureTask(Runnable runnable, V result) {
      }
      

      事實上,FutureTask是Future接口的一個唯一實現類。

      四.使用示例

      1.使用Callable+Future獲取執行結果

      public class Test {
          public static void main(String[] args) {
              ExecutorService executor = Executors.newCachedThreadPool();
              Task task = new Task();
              Future<Integer> result = executor.submit(task);
              executor.shutdown();
               
              try {
                  Thread.sleep(1000);
              } catch (InterruptedException e1) {
                  e1.printStackTrace();
              }
               
              System.out.println("主線程在執行任務");
               
              try {
                  System.out.println("task運行結果"+result.get());
              } catch (InterruptedException e) {
                  e.printStackTrace();
              } catch (ExecutionException e) {
                  e.printStackTrace();
              }
               
              System.out.println("所有任務執行完畢");
          }
      }
      class Task implements Callable<Integer>{
          @Override
          public Integer call() throws Exception {
              System.out.println("子線程在進行計算");
              Thread.sleep(3000);
              int sum = 0;
              for(int i=0;i<100;i++)
                  sum += i;
              return sum;
          }
      }
      

      執行結果:

      子線程在進行計算
      主線程在執行任務
      task運行結果4950
      所有任務執行完畢
      

      2.使用Callable+FutureTask獲取執行結果

      public class Test {
          public static void main(String[] args) {
              //第一種方式
              ExecutorService executor = Executors.newCachedThreadPool();
              Task task = new Task();
              FutureTask<Integer> futureTask = new FutureTask<Integer>(task);
              executor.submit(futureTask);
              executor.shutdown();
               
              //第二種方式,注意這種方式和第一種方式效果是類似的,只不過一個使用的是ExecutorService,一個使用的是Thread
              /*Task task = new Task();
              FutureTask<Integer> futureTask = new FutureTask<Integer>(task);
              Thread thread = new Thread(futureTask);
              thread.start();*/
               
              try {
                  Thread.sleep(1000);
              } catch (InterruptedException e1) {
                  e1.printStackTrace();
              }
               
              System.out.println("主線程在執行任務");
               
              try {
                  System.out.println("task運行結果"+futureTask.get());
              } catch (InterruptedException e) {
                  e.printStackTrace();
              } catch (ExecutionException e) {
                  e.printStackTrace();
              }
               
              System.out.println("所有任務執行完畢");
          }
      }
      class Task implements Callable<Integer>{
          @Override
          public Integer call() throws Exception {
              System.out.println("子線程在進行計算");
              Thread.sleep(3000);
              int sum = 0;
              for(int i=0;i<100;i++)
                  sum += i;
              return sum;
          }
      }
      

      如果為了可取消性而使用 Future 但又不提供可用的結果,則可以聲明 Future<?> 形式類型、并返回 null 作為底層任務的結果。

      posted @ 2024-07-10 09:58  booleandev  閱讀(22)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 另类 专区 欧美 制服丝袜| 久久99热成人精品国产| 亚洲av永久一区二区| 亚洲av无码专区在线厂| 又大又粗又硬又爽黄毛少妇| 国产av一区二区三区久久| 欧美亚洲另类制服卡通动漫 | 五月天中文字幕mv在线| 亚洲天堂男人天堂女人天堂| 日本一区三区高清视频| аⅴ天堂中文在线网| 亚洲成人av在线资源| 亚洲日韩日本中文在线| 四虎永久在线精品8848a| 亚洲V天堂V手机在线| 一二三四日本高清社区5| 亚洲天堂亚洲天堂亚洲色图| 中文字幕亚洲人妻一区| 中文字幕乱码视频32| 午夜成年男人免费网站| 99国精品午夜福利视频不卡99 | 亚洲av熟女国产一二三| 中文字幕国产精品自拍| 人妻蜜臀久久av不卡| 欧美黑人大战白嫩在线| 亚洲香蕉网久久综合影视| 宜兴市| 亚洲成人av一区二区| 国产偷国产偷亚洲综合av| 成全影视大全在线观看| 亚洲综合伊人久久大杳蕉| 亚洲综合精品香蕉久久网| 香蕉久久一区二区不卡无毒影院| 午夜激情小视频一区二区| 九九在线精品国产| 日本精品一区二区不卡| 亚洲色大成网站www永久男同| 亚洲中文在线精品国产| 亚洲成av人片无码迅雷下载| 国产女人水真多18毛片18精品| 亚洲天堂男人的天堂在线|