1. 程式人生 > >(面試題)模擬 主程序需要等待多個子程序結束之後再執行後續的程式碼的實現

(面試題)模擬 主程序需要等待多個子程序結束之後再執行後續的程式碼的實現

解法1. Thread.join方法

import java.util.Vector;

public class Test {
    public static void main(String[] args) throws InterruptedException {
    /*
    Vector集合: JDK1.0 底層也是陣列  是最早期的同步集合 也就意味著是單執行緒 效率低 
    			實現了list介面所以可以使用list的所有方法  
      	特有方法:
      	 void addElement(E obj) 將指定的元件新增到此向量的末尾,將其大小增加 1 
      	 Enumeration<E> elements() 返回此向量的元件的列舉(早期的迭代器)。 
      */
        Vector<Thread> vector = new Vector<>();
        for (int i = 0; i < 5; i++) {
            Thread childThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("子執行緒被執行");
                }
            });
            vector.add(childThread);
            childThread.start();
        }
        for (Thread thread : vector) {
        // void join()  等待該執行緒終止
            thread.join();
        }
        System.out.println("主執行緒被執行");
    }
}

解法2.等待多執行緒完成的CountDownLatch

  • 1.CountDownLatch的概念: extends Object CountDownLatch是一個同步工具類,用來協調多個執行緒之間的同步 或者說起到執行緒之間的通訊(而不是互斥的作用) CountDownLatch能夠使一個執行緒在等待另一些執行緒完成自己任務後, 再繼續執行.使用一個計數器進行實現,計數器初始值為執行緒的總數量(包括主執行緒). 當每一個執行緒完成自己任務後,計數器的值減一.當計數器的值為0時,表示所有執行緒執行完成, 然後在CountDownLatch上等待的執行緒可以恢復執行任務.

  • 2.CountDownLatch的典型用法: 典型用法1: 某一個執行緒開始執行前等待n個執行緒執行完畢.將CountDownLatch的計數器初始化 new CountDownLatch(n),每當一個執行緒完成任務後,計數器的值就會減一 CountDownLatch.countDown(),當計數器的值為0時,在CountDownLatch上await()的執行緒就會被喚醒. 應用場景:啟動一個服務時,主執行緒需要等待多個元件載入完畢之後再繼續執行.

    典型用法2:實現多個執行緒開始執行任務的最大並行性.這裡時並行,不是併發, 強調的是多個執行緒在某一時刻同時開始執行.類似於賽跑,將多個執行緒放到七點,等待發令槍,然後同時執行. 做法是初始化一個共享的CountDownLatch(1),將其計數器初始化為1.多個執行緒開始執行任務前首先CountDownLatch.await().當主執行緒呼叫countDown()時,計數器變為0,多個執行緒同時被喚醒.

  • 3.CountDownLatch的不足: CountDownLatch是一次性的,計數器的值只能在構造方法中初始化一次,之後沒有任何機制能夠再次對其設定值, 當CountDownLatch使用完畢後,不能再次被呼叫.

 public static void main(String[] args) throws InterruptedException {
        //建立CountDownLatch並初始化為5
        CountDownLatch latch = new CountDownLatch(5);
        for (int i = 0; i < 5; i++) {
            Thread childthread = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("子執行緒開始執行");
                    //計數器遞減,為0時釋放所有執行緒
                    latch.countDown();
                }
            });
            childthread.start();
        }
        //設定主執行緒等待
        latch.await();
        System.out.println("主執行緒開始執行");
    }