java中join()方法的使用

Java中Thread類提供join()方法。

作用:用於在當前線程A中添加別的線程B,這時線程A被阻塞,處於Blocked狀態,線程B開始執行,當線程B執行完以後,線程A處於可運行狀(Runnable),等待cpu的調度再執行。

用法:當前線程A必須先用myThread的start()啓動線程(否則join()不會被執行),然後調用join():
//線程A中的代碼
myThread.start();
myThread.join();
//線程A中的代碼

實例:
1. 實現Runnable接口,重寫run方法

public class MyTask implements Runnable {
        private int taskNum;
        private Thread thread = null;
        public MyTask(int num) {
            this.taskNum = num;
        }
        public MyTask(int num, Thread thread) {
            this.taskNum = num;
            this.thread = thread;
        }
        @Override
        public void run() {
            System.out.println("正在執行task " + taskNum);
            try {
                if (thread != null) {
                    System.out.println("join的線程開始執行");
                    thread.start();//****在當前線程中啓動要添加的線程****//
                    thread.join();//****執行join()方法****//
                    System.out.println("join的線程執行完畢");
                    System.out.println("繼續執行當前線程");
                }
                Thread.sleep(taskNum * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("task " + taskNum + " 執行完畢");
        }
    }
  1. 編寫測試類:
public class Main {
            public static void main(String[] args) throws InterruptedException {
                System.out.println(Thread.currentThread().getName() + "開始執行");
                Thread thread2 = new Thread(new MyTask(10));
                Thread thread1 = new Thread(new MyTask(5, thread2));
                thread1.start();
                thread1.join();
                System.out.println(Thread.currentThread().getName() + "執行完畢");
            }
        }

在main線程中添加thread1線程,main線程被阻塞,thread1開始執行;
thread1中有添加了thread2線程,thread將被阻塞,直到thread2執行完畢;
3. 結果:main開始執行–>task1開始執行–>task2開始執行–>task2執行完畢–>task1執行完畢–>main執行完畢
main開始
正在執行task 1
join的線程開始執行
正在執行task 2
task 2 執行完畢
join的線程執行完畢
繼續執行當前線程
task 1 執行完畢
main執行完畢
4. JDK中join()的實現

    public final void join() throws InterruptedException {
            join(0);
        }

        public final synchronized void join(long millis)
        throws InterruptedException {
            long base = System.currentTimeMillis();
            long now = 0;
            if (millis < 0) {
                throw new IllegalArgumentException("timeout value is negative");
            }

        if (millis == 0) {
            while (isAlive()) {
                wait(0);
            }
        } else {
            while (isAlive()) {//****表明如果myThread.join()中的myThread執行完畢變成dead狀態,則退出循環,返回調用myThread.join()的線程繼續執行
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
       }

所以有兩種方式調用join()方法:
(1).myThread.join();//不指定當前線程wait的時間,這會導致當前線程一直阻塞至myThread執行完畢
(2).myThread.join(long time);//指定當前線程wait時間,這回導致當前線程一直阻塞time毫秒或者myThread執行完畢
5. 測試join(long time)
修改上文的MyTask類

public class MyTask implements Runnable {
    private int taskNum;
    private Thread thread = null;

    public MyTask(int num) {
        this.taskNum = num;
    }

    public MyTask(int num, Thread thread) {
        this.taskNum = num;
        this.thread = thread;
    }

    @Override
    public void run() {
        System.out.println("正在執行task " + taskNum);
        try {
            if (thread != null) {
                System.out.println("join的線程開始執行");
                long start = System.currentTimeMillis();
                thread.start();
                thread.join(3000);
                long end = System.currentTimeMillis();
                System.out.println("join的線程執行完畢,用時" + (end - start) + "毫秒");
                System.out.println("繼續執行當前線程");
            }
            Thread.sleep(taskNum * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("task " + taskNum + " 執行完畢");
    }
}
  1. 結果
    main開始執行
    正在執行task 1
    join的線程開始執行
    正在執行task 2
    task 2 執行完畢
    join的線程執行完畢,用時2000毫秒//表明join的線程執行完畢以後就返回了
    繼續執行當前線程
    task 1 執行完畢
    main執行完畢
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章