您好,登錄后才能下訂單哦!
本篇內容主要講解“如何讓主線程等待所有的子線程結束之后再執行”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“如何讓主線程等待所有的子線程結束之后再執行”吧!
package com.qcy.testThreadFinish; /** * @author qcy * @create 2020/09/09 17:05:23 */ public class Case1 { public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(() -> { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } }); t1.start(); Thread t2 = new Thread(() -> { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } }); t2.start(); t1.join(); t2.join(); System.out.println("主線程結束"); } }
join()方法使得主線程等待子線程執行結束,阻塞的是主線程。其底層原理,可以參考我的這篇文章你真得懂Thread.join嗎?
package com.qcy.testThreadFinish; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * @author qcy * @create 2020/09/09 17:05:23 */ public class Case2 { public static void main(String[] args) { ExecutorService pool = Executors.newFixedThreadPool(3); pool.execute(() -> { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } }); pool.execute(() -> { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } }); //不再接受新的任務 pool.shutdown(); while (true) { //手動循環確實效率很低,不推薦 if (pool.isTerminated()) { System.out.println("線程池中的任務執行結束"); break; } } System.out.println("主線程結束"); } }
isTerminated,當調用shutdown()方法后,并且所有提交的任務完成后才會返回為true
這里直接使用了固定大小的線程池,線程池的參數在面試中也經常被問到,對線程池不熟悉的同學,可以參考我的這篇文章說說線程池
package com.qcy.testThreadFinish; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; /** * @author qcy * @create 2020/09/09 17:05:23 */ public class Case4 { public static void main(String[] args) throws ExecutionException, InterruptedException { ExecutorService pool = Executors.newFixedThreadPool(3); Future<Integer> task1 = pool.submit(() -> { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } return 2; }); Future<Integer> task2 = pool.submit(() -> { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } return 3; }); //不再接受新的任務 pool.shutdown(); //get方法為阻塞獲取 System.out.println("task1的運行結果:" + task1.get()); System.out.println("task2的運行結果:" + task2.get()); System.out.println("主線程結束"); } }
Future機制,可以參考我的另外一篇博客談談Future、Callable、FutureTask關系
package com.qcy.testThreadFinish; import java.util.concurrent.CountDownLatch; /** * @author qcy * @create 2020/09/09 17:05:23 */ public class Case5 { public static void main(String[] args) throws InterruptedException { CountDownLatch latch = new CountDownLatch(2); Thread t1 = new Thread(() -> { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } finally { latch.countDown(); } }); t1.start(); Thread t2 = new Thread(() -> { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } finally { latch.countDown(); } }); t2.start(); latch.await(); System.out.println("主線程結束"); } }
每調用一次countDown方法,計數器會減1,在計數器減為0之前,await方法將會阻塞主線程。有關CountDownLatch的底層原理,可以參考我的另外一篇博客CountDownLatch實現原理
package com.qcy.testThreadFinish; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; /** * @author qcy * @create 2020/09/09 17:05:23 */ public class Case6 { public static void main(String[] args) throws InterruptedException, ExecutionException { CompletableFuture<Integer> cf1 = CompletableFuture.supplyAsync(() -> { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } return 2; }); CompletableFuture<Integer> cf = CompletableFuture.supplyAsync(() -> { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } return 3; }).thenCombine(cf1, (result1, result2) -> result1 * result2); //get方法為阻塞獲取 System.out.println("計算結果為" + cf.get()); System.out.println("主線程結束"); } }
等到兩個子任務都完成后,輸出兩數之積,再執行主線程。
到此,相信大家對“如何讓主線程等待所有的子線程結束之后再執行”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。