Java中等待線程執行完畢

前言:前一段時間在做項目的時候,某段代碼中用到了多線程,該處代碼需要開啓多個線程,待這幾個線程執行完畢後再接着執行後續的流程。現將可採用的方法記錄如下。


要達到上述的描述的情形,可以使用Thread的join()方法,也可以使用java.util.concurrent包中的CountDownLatch類。具體如下:

一、使用Thread.join()方法

該方法在JDK API中的解釋爲“等待該線程終止”,存在三個方法重載,如下:
void join();
void join(long millis); // 等待該線程終止的最長時間爲millis毫秒
void join(long millis, int nanos); // 等待該線程終止的最長時間爲millis毫秒+nanos納秒

代碼如下:

package threadTest;

import java.util.Vector;
import java.util.concurrent.*;

/**
 * Created by worm0527 on 2017/7/17.
 */
public class ThreadTest extends Thread {

    // 線程名稱
    private String threadName;

    // 線程休眠時間
    private int sleepSec;

    ThreadTest(String threadName, int sleepSec) {
        super(threadName);
        this.sleepSec = sleepSec;
        start();// 在構造方法中啓動線程
    }

    @Override
    public void run() {
        long starttime = System.currentTimeMillis();
        System.out.println(Thread.currentThread().getName() + " running...");
        try {
            // 休眠制定時間(單位:秒)
            TimeUnit.SECONDS.sleep(sleepSec);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + " run at " + (System.currentTimeMillis() - starttime) + " ms");
    }

    public static void main(String[] args) throws InterruptedException {

        long starttime = System.currentTimeMillis();
        System.out.println("Thread main running...");

        Vector<Thread> threadVector = new Vector<Thread>();
        for (int i = 1; i < 5; i++) { // 開啓四個線程
            Thread t = new ThreadTest("Thread" + i, i);
            threadVector.add(t);
        }

        for (Thread t : threadVector) { // 循環調用線程join()方法,等待線程結束
            t.join();
        }

        System.out.println("Thread main End");
        System.out.println("Thread main run at " + (System.currentTimeMillis() - starttime) + " ms");
    }
}

運行結果:

運行結果

二、使用CountDownLatch類

主要使用了該類的await()和countDown()兩個方法。await()阻塞線程,直到計數器歸零或者線程被中斷,調用countDown()來遞減計數器。

代碼如下:

package threadTest;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * Created by worm0527 on 2017/7/18.
 */
public class ThreadTest1 extends Thread {

    // 線程名稱
    private String threadName;

    // 線程休眠時間
    private int sleepSec;

    private CountDownLatch latch; // 線程類中持有CountDownLatch對象的引用

    public ThreadTest1(String threadName, int sleepSec, CountDownLatch latch) {
        super(threadName);
        this.sleepSec = sleepSec;
        this.latch = latch;
        start();// 在構造方法中啓動線程
    }

    @Override
    public void run() {
        long starttime = System.currentTimeMillis();
        System.out.println(Thread.currentThread().getName() + " running...");
        try {
            // 休眠制定時間(單位:秒)
            TimeUnit.SECONDS.sleep(sleepSec);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + " run at " + (System.currentTimeMillis() - starttime) + " ms");
        latch.countDown();
    }

    public static void main(String[] args) throws InterruptedException {

        long starttime = System.currentTimeMillis();
        System.out.println("Thread main running...");

        CountDownLatch latch = new CountDownLatch(4); // 共四個子線程
        for (int i = 1; i < 5; i++) {
            new ThreadTest1("Thread" + i, i, latch);
        }
        latch.await(); // 阻塞,直到線程計數歸零

        System.out.println("Thread main End");
        System.out.println("Thread main run at " + (System.currentTimeMillis() - starttime) + " ms");
    }

}

運行結果:

運行結果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章