自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

面試官:如何讓主線程等待所有的子線程結(jié)束之后再執(zhí)行?我懵了

開(kāi)發(fā) 前端
當(dāng)面試官問(wèn)你,如何讓主線程等待所有的子線程結(jié)束之后再執(zhí)行?你知道嗎?本篇就帶給大家這個(gè)問(wèn)題的答案。

[[391867]]

使用Thread的join方法

  1. package com.qcy.testThreadFinish; 
  2.  
  3. /** 
  4.  * @author qcy 
  5.  * @create 2020/09/09 17:05:23 
  6.  */ 
  7. public class Case1 { 
  8.     public static void main(String[] args) throws InterruptedException { 
  9.  
  10.         Thread t1 = new Thread(() -> { 
  11.             try { 
  12.                 Thread.sleep(3000); 
  13.             } catch (InterruptedException e) { 
  14.                 e.printStackTrace(); 
  15.             } 
  16.         }); 
  17.         t1.start(); 
  18.  
  19.         Thread t2 = new Thread(() -> { 
  20.             try { 
  21.                 Thread.sleep(3000); 
  22.             } catch (InterruptedException e) { 
  23.                 e.printStackTrace(); 
  24.             } 
  25.         }); 
  26.         t2.start(); 
  27.  
  28.         t1.join(); 
  29.         t2.join(); 
  30.         System.out.println("主線程結(jié)束"); 
  31.     } 

 join()方法使得主線程等待子線程執(zhí)行結(jié)束,阻塞的是主線程。其底層原理,可以參考我的這篇文章你真得懂Thread.join嗎?

使用線程池的isTerminated方法

  1. package com.qcy.testThreadFinish; 
  2.  
  3. import java.util.concurrent.ExecutorService; 
  4. import java.util.concurrent.Executors; 
  5.  
  6. /** 
  7.  * @author qcy 
  8.  * @create 2020/09/09 17:05:23 
  9.  */ 
  10. public class Case2 { 
  11.     public static void main(String[] args) { 
  12.  
  13.         ExecutorService pool = Executors.newFixedThreadPool(3); 
  14.  
  15.         pool.execute(() -> { 
  16.             try { 
  17.                 Thread.sleep(2000); 
  18.             } catch (InterruptedException e) { 
  19.                 e.printStackTrace(); 
  20.             } 
  21.         }); 
  22.  
  23.         pool.execute(() -> { 
  24.             try { 
  25.                 Thread.sleep(2000); 
  26.             } catch (InterruptedException e) { 
  27.                 e.printStackTrace(); 
  28.             } 
  29.         }); 
  30.  
  31.         //不再接受新的任務(wù) 
  32.         pool.shutdown(); 
  33.          
  34.         while (true) { 
  35.             //手動(dòng)循環(huán)確實(shí)效率很低,不推薦 
  36.             if (pool.isTerminated()) { 
  37.                 System.out.println("線程池中的任務(wù)執(zhí)行結(jié)束"); 
  38.                 break; 
  39.             } 
  40.         } 
  41.         System.out.println("主線程結(jié)束"); 
  42.     } 

isTerminated,當(dāng)調(diào)用shutdown()方法后,并且所有提交的任務(wù)完成后才會(huì)返回為true

這里直接使用了固定大小的線程池,線程池的參數(shù)在面試中也經(jīng)常被問(wèn)到,對(duì)線程池不熟悉的同學(xué),可以參考我的這篇文章說(shuō)說(shuō)線程池

使用Future機(jī)制

  1. package com.qcy.testThreadFinish; 
  2.  
  3. import java.util.concurrent.ExecutionException; 
  4. import java.util.concurrent.ExecutorService; 
  5. import java.util.concurrent.Executors; 
  6. import java.util.concurrent.Future; 
  7.  
  8. /** 
  9.  * @author qcy 
  10.  * @create 2020/09/09 17:05:23 
  11.  */ 
  12. public class Case4 { 
  13.     public static void main(String[] args) throws ExecutionException, InterruptedException { 
  14.  
  15.         ExecutorService pool = Executors.newFixedThreadPool(3); 
  16.  
  17.         Future<Integer> task1 = pool.submit(() -> { 
  18.             try { 
  19.                 Thread.sleep(2000); 
  20.             } catch (InterruptedException e) { 
  21.                 e.printStackTrace(); 
  22.             } 
  23.             return 2; 
  24.         }); 
  25.  
  26.         Future<Integer> task2 = pool.submit(() -> { 
  27.             try { 
  28.                 Thread.sleep(2000); 
  29.             } catch (InterruptedException e) { 
  30.                 e.printStackTrace(); 
  31.             } 
  32.             return 3; 
  33.         }); 
  34.  
  35.         //不再接受新的任務(wù) 
  36.         pool.shutdown(); 
  37.          
  38.         //get方法為阻塞獲取 
  39.         System.out.println("task1的運(yùn)行結(jié)果:" + task1.get()); 
  40.         System.out.println("task2的運(yùn)行結(jié)果:" + task2.get()); 
  41.  
  42.         System.out.println("主線程結(jié)束"); 
  43.     } 

Future機(jī)制,可以參考我的另外一篇博客談?wù)凢uture、Callable、FutureTask關(guān)系

使用CountDownLatch

  1. package com.qcy.testThreadFinish; 
  2.  
  3. import java.util.concurrent.CountDownLatch; 
  4.  
  5. /** 
  6.  * @author qcy 
  7.  * @create 2020/09/09 17:05:23 
  8.  */ 
  9. public class Case5 { 
  10.     public static void main(String[] args) throws InterruptedException { 
  11.  
  12.         CountDownLatch latch = new CountDownLatch(2); 
  13.  
  14.         Thread t1 = new Thread(() -> { 
  15.             try { 
  16.                 Thread.sleep(3000); 
  17.             } catch (InterruptedException e) { 
  18.                 e.printStackTrace(); 
  19.             } finally { 
  20.                 latch.countDown(); 
  21.             } 
  22.         }); 
  23.         t1.start(); 
  24.  
  25.         Thread t2 = new Thread(() -> { 
  26.             try { 
  27.                 Thread.sleep(3000); 
  28.             } catch (InterruptedException e) { 
  29.                 e.printStackTrace(); 
  30.             } finally { 
  31.                 latch.countDown(); 
  32.             } 
  33.         }); 
  34.         t2.start(); 
  35.  
  36.         latch.await(); 
  37.         System.out.println("主線程結(jié)束"); 
  38.     } 

每調(diào)用一次countDown方法,計(jì)數(shù)器會(huì)減1,在計(jì)數(shù)器減為0之前,await方法將會(huì)阻塞主線程。有關(guān)CountDownLatch的底層原理,可以參考我的另外一篇博客CountDownLatch實(shí)現(xiàn)原理

使用CompletableFuture

  1. package com.qcy.testThreadFinish; 
  2.  
  3. import java.util.concurrent.CompletableFuture; 
  4. import java.util.concurrent.ExecutionException; 
  5.  
  6. /** 
  7.  * @author qcy 
  8.  * @create 2020/09/09 17:05:23 
  9.  */ 
  10. public class Case6 { 
  11.     public static void main(String[] args) throws InterruptedException, ExecutionException { 
  12.  
  13.         CompletableFuture<Integer> cf1 = CompletableFuture.supplyAsync(() -> { 
  14.             try { 
  15.                 Thread.sleep(3000); 
  16.             } catch (InterruptedException e) { 
  17.                 e.printStackTrace(); 
  18.             } 
  19.             return 2; 
  20.         }); 
  21.  
  22.         CompletableFuture<Integer> cf = CompletableFuture.supplyAsync(() -> { 
  23.             try { 
  24.                 Thread.sleep(3000); 
  25.             } catch (InterruptedException e) { 
  26.                 e.printStackTrace(); 
  27.             } 
  28.             return 3; 
  29.         }).thenCombine(cf1, (result1, result2) -> result1 * result2); 
  30.  
  31.         //get方法為阻塞獲取 
  32.         System.out.println("計(jì)算結(jié)果為" + cf.get()); 
  33.         System.out.println("主線程結(jié)束"); 
  34.     } 

等到兩個(gè)子任務(wù)都完成后,輸出兩數(shù)之積,再執(zhí)行主線程。對(duì)CompletableFuture不熟悉的同學(xué),可以參考我的這一篇文章什么,你還不會(huì)用CompletableFuture?

 

責(zé)任編輯:姜華 來(lái)源: 今日頭條
相關(guān)推薦

2020-05-22 08:11:48

線程池JVM面試

2019-08-28 14:25:00

線程安全容器

2024-09-11 22:51:19

線程通訊Object

2022-04-10 18:10:24

CURD鏈表

2021-11-29 10:55:11

線程池Java面試

2024-05-08 00:00:00

核心線程數(shù)隊(duì)列

2024-09-12 08:35:06

2024-09-09 15:09:30

2024-04-02 09:45:27

線程池Executors開(kāi)發(fā)

2021-05-08 07:53:33

面試線程池系統(tǒng)

2023-02-04 07:34:12

URLIP身份定位

2020-09-17 17:53:12

面試ArrayList數(shù)組

2022-03-30 08:54:21

線程 Thread判斷線程池任務(wù)Java

2023-12-20 14:35:37

Java虛擬線程

2024-03-11 18:18:58

項(xiàng)目Spring線程池

2020-06-22 08:50:27

Spring AOP代理

2024-04-10 09:47:59

Java調(diào)度虛擬線程

2022-06-24 06:43:57

線程池線程復(fù)用

2010-02-24 11:19:00

Python主線程

2021-11-12 06:39:51

Tomcat連接器面試
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)