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

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

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

      三種線程創建的方式

      本篇內容為線程專題 -- 線程的創建,狀態,工作過程中的線程創建方式的部分內容。

      JAVA中有三種線程創建的方式:

      (1)實現Runnable接口的run方法。

      (2)繼承Thread類并重寫run的方法。

      (3)使用FutureTask方式(實現Callable接口的方式)。

      說明:在《Java并發編程之美》書中第(3)種創建方式描述為:使用FutureTask方式。

       繼承Thread類的方式的實現

       1 /**
       2  * 創建線程方式--繼承Thread類的方式的實現
       3  * @author JustJavaIt
       4  */
       5 public class ThreadTest {
       6 
       7     public static void main(String[] args) {
       8         //創建線程
       9         MyThread thread = new MyThread();
      10         //啟動線程
      11         thread.start();
      12         System.out.println("I am main thread");
      13     }
      14 
      15     /**
      16      * 繼承Thread類,并重寫run方法
      17      */
      18     public static class MyThread extends Thread{
      19         @Override
      20         public void run() {
      21             System.out.println("I am a child thread");
      22         }
      23     }
      24 }
      View Code

      運行結果如下:

        如上代碼中的MyThread類繼承了Thread類,并重寫了run()方法。在main函數里面創建了一個MyThread的實例,然后調用該實例的start方法啟動了線程。需要注意的是, 當創建完thread對象后該線程并沒有被啟動執行,直到調用了start方法后才真正啟動了線程

        其實調用start方法后線程并沒有馬上執行而是處于就緒狀態,這個就緒狀態是指該線程已經獲取了除CPU資源外的其他資源,等待獲取CPU資源后才會真正處于運行狀態。 一旦run方法執行完畢,該線程就處于終止狀態。

        使用繼承方式的好處是,在run()方法內獲取當前線程直接使用this就可以了,無須使用Thread.currentThread()方法;不好的地方是Java不支持多繼承,如果繼承了Thread類, 那么就不能再繼承其他類。另外任務與代碼沒有分離,當多個線程執行一樣的任務時需要 多份任務代碼,而Runable則沒有這個限制。

      實現Runnable接口的run方法方式

       1 /**
       2  * 創建線程方式--實現Runnable接口的run方法。
       3  * @author JustJavaIt
       4  * @date 2022/2/12 16:21
       5  */
       6 public class RunableTest {
       7     public static void main(String[] args) {
       8         RunableTask task = new RunableTask();
       9         //任務和代碼分離,當多個線程執行一樣任務時不用多份任務代碼。
      10         new Thread(task).start();
      11         new Thread(task).start();
      12     }
      13 
      14     public static class RunableTask implements Runnable{
      15 
      16         @Override
      17         public void run() {
      18             System.out.println("I am a child thread");
      19         }
      20     }
      21 }
      View Code

      運行結果如下:

      如上代碼所示,兩個線程共用一個task代碼邏輯,如果需要,可以給RunableTask添加參數進行任務區分。另外,RunableTask可以繼承其他類。但是上面介紹的兩種方式都有一個缺點,就是任務沒有返回值。

      使用FutureTask方式(實現Callable接口的方式)

        通過實現callable接口的方式,可以創建一個線程,需要重寫其中的call方式。啟動線程時,需要創建一個Callable的實例,再用FutureTask實例包裝它,最終,再包裝成Thread實例,調用start()啟動,并且,可以通過FutureTask的get方法來獲取返回值。

      FutureTask介紹

        在Java并發程序中FutureTask表示一個可以取消的異步運算。它有啟動和取消運算、查詢運算是否完成和取回運算結果等方法。只有當運算完成的時候結果才能取回,如果運算尚未完成get方法將會阻塞。一個FutureTask對象可以對調用了Callable和Runnable的對象進行包裝,由于FutureTask也是調用了Runnable接口所以它可以提交給Executor來執行。

       1 /**
       2  * 創建線程方式--使用FutureTask方式 Page21
       3  * @author JustJavaIt
       4  */
       5 public class FutureTasktest {
       6     public static void main(String[] args) {
       7         CallerTask callerTask = new CallerTask();
       8         //創建異步任務
       9         FutureTask<String> futureTask = new FutureTask<>(callerTask);
      10         //啟動線程
      11         new Thread(futureTask).start();
      12         String result;
      13         try {
      14             //等待任務執行完畢,并返回結果。
      15             result = futureTask.get();
      16             System.out.println("result:"+ result);
      17         } catch (InterruptedException e) {
      18             e.printStackTrace();
      19         } catch (ExecutionException e) {
      20             e.printStackTrace();
      21         }
      22     }
      23 
      24     /**
      25      * 創建任務類,類似Runable
      26      */
      27     public static class CallerTask implements Callable<String>{
      28 
      29         @Override
      30         public String call() throws Exception {
      31             return "hello";
      32         }
      33     }
      34 }
      View Code

      運行結果如下:

        如上代碼中的CallerTask類實現了Callable接口的call()方法。在main函數內首先創建了一個FutrueTask對象(構造函數為CallerTask的實例),然后使用創建的FutrueTask對象作為任務創建了一個線程并且啟動它,最后通過futureTask.get()等待任務執行完畢并返回結果。

        小結:使用繼承方式的好處是方便傳參,你可以在子類里面添加成員變量,通過set方法設置參數或者通過構造函數進行傳遞,而如果使用Runnable方式,則只能使用主線程里面被聲明為final的變量。不好的地方是Java不支持多繼承,如果繼承了Thread類, 那么子類不能再繼承其他類,而Runable則沒有這個限制。前兩種方式都沒辦法拿到任務的返回結果,但是Futuretask方式可以

      補充

      FutureTask和Future示例

       FutureTask是Future和Callable的結合體和Callable的結合體

       1 /**
       2  * FutureTask示例
       3  * @author JustJavait
       4  * @date 2022/1/12 18:02
       5  */
       6 public class CallableFutureTask {
       7     public static void main(String[] args) {
       8         //第一種方式 線程池
       9         ExecutorService executor = Executors.newCachedThreadPool();
      10         Task1 task1 = new Task1();
      11         FutureTask<Integer> futureTask = new FutureTask<>(task1);
      12         executor.submit(futureTask);
      13         executor.shutdown();
      14 
      15         //第二種方式,注意這種方式和第一種方式效果是類似的,只不過一個使用的是ExecutorService,一個使用的是Thread
      16        /* Task1 task1 = new Task1();
      17         FutureTask<Integer> futureTask = new FutureTask<>(task1);
      18         Thread thread = new Thread(futureTask);
      19         thread.start();*/
      20 
      21         try {
      22             Thread.sleep(1000);
      23         } catch (InterruptedException e1) {
      24             e1.printStackTrace();
      25         }
      26 
      27         System.out.println("主線程在執行任務");
      28 
      29         try {
      30             System.out.println("task運行結果" + futureTask.get());
      31         } catch (InterruptedException e) {
      32             e.printStackTrace();
      33         } catch (ExecutionException e) {
      34             e.printStackTrace();
      35         }
      36 
      37         System.out.println("所有任務執行完畢");
      38     }
      39 }
      40 
      41 class Task1 implements Callable<Integer> {
      42     @Override
      43     public Integer call() throws Exception {
      44         System.out.println("子線程在進行計算");
      45         Thread.sleep(3000);
      46         int sum = 0;
      47         for (int i = 0; i < 100; i++) {
      48             sum += i;
      49         }
      50         return sum;
      51     }
      52 }
      View Code
       1 /**
       2  * Future示例
       3  * @author JustJavait
       4  * @date 2022/1/12 17:55
       5  */
       6 public class CallableFuture {
       7     public static void main(String[] args) {
       8         ExecutorService executor = Executors.newCachedThreadPool();
       9         Task task = new Task();
      10         Future<Integer> result = executor.submit(task);
      11         executor.shutdown();
      12 
      13         try {
      14             Thread.sleep(1000);
      15         } catch (InterruptedException e1) {
      16             e1.printStackTrace();
      17         }
      18 
      19         System.out.println("主線程在執行任務");
      20 
      21         try {
      22             System.out.println("task運行結果" + result.get());
      23         } catch (InterruptedException e) {
      24             e.printStackTrace();
      25         } catch (ExecutionException e) {
      26             e.printStackTrace();
      27         }
      28 
      29         System.out.println("所有任務執行完畢");
      30     }
      31 }
      32 
      33 class Task implements Callable<Integer> {
      34     @Override
      35     public Integer call() throws Exception {
      36         System.out.println("子線程在進行計算");
      37         Thread.sleep(3000);
      38         int sum = 0;
      39         for (int i = 0; i < 100; i++) {
      40             sum += i;
      41         }
      42         return sum;
      43     }
      44 }
      View Code

      運行結果都為:

       三種方式的區別?

      Java中,類僅支持單繼承,如果一個類繼承了Thread類,就無法再繼承其它類,因此,如果一個類既要繼承其它的類,又必須創建為一個線程,就可以使用實現Runable接口的方式。

      使用實現Runable接口的方式創建的線程可以處理同一資源,實現資源的共享。

      使用實現Callable接口的方式創建的線程,可以獲取到線程執行的返回值、是否執行完成等信息。

      Java中Runnable和Callable有什么不同?

      Runnable和Callable都是創建線程的方式。Runnable從JDK1.0開始就有了,Callable是在JDK1.5增加的。

      (1)實現Callable接口的任務線程能返回執行結果;而實現Runnable接口的任務線程不能返回結果;

      (2)Callable接口的call()方法允許拋出異常;而Runnable接口的run()方法的異常只能在內部消化,不能繼續上拋;

       <END>

      ??希望本文章對您有幫助,您的 轉發、點贊 是我創作的無限動力。

      掃描下方二維碼關注微信公眾號,您會收到更多優質文章推送。

      posted @ 2022-02-13 17:47  JustJavaIt  閱讀(1166)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产午夜一区二区在线观看| 亚洲一区二区三区在线观看精品中文| 精品视频在线观自拍自拍| 亚洲人午夜精品射精日韩| 国产乱色国产精品免费视频 | 国产线播放免费人成视频播放| 少妇人妻系列无码专区视频| 美女一区二区三区亚洲麻豆| 三上悠亚精品二区在线观看| 日本一区二区不卡精品| 成人精品视频一区二区三区 | 中文国产不卡一区二区| 四虎国产精品永久地址99| 久久高潮少妇视频免费| 日韩丝袜人妻中文字幕| 思思热在线视频精品| 幻女free性俄罗斯毛片| 中文字幕无码视频手机免费看| 国产极品嫩模在线观看91| 中文熟妇人妻av在线| 亚洲中文字幕久在线| 国产精品国产三级国产专业| 爱性久久久久久久久| 国产日韩一区二区在线| 俄罗斯老熟妇性爽xxxx| 国产成人精品97| 亚洲中文字幕无码一久久区| 中文字幕一区二区人妻| 国产精品福利自产拍久久| 国产亚洲精品成人aa片新蒲金| 亚洲色欲色欱WWW在线| 国产在线国偷精品产拍| 亚洲不卡av不卡一区二区| 99久久免费精品色老| 国产精品污www在线观看| 麻豆国产高清精品国在线| 精品偷拍被偷拍在线观看| 欧美成人aaa片一区国产精品| 国内自拍第一区二区三区| 国产无套精品一区二区 | 久久久久成人精品无码中文字幕|