文章目錄
一、join()方法的作用
二、join()和start()調用順序問題
三、join()方法實現原理
一、join()方法的作用
主要作用是同步,它可以使得線程之間的並行執行變爲串行執行。在A線程中調用了B線程的join()方法時,表示只有當B線程執行完畢時,A線程才能繼續執行。
看如下代碼
class JoinThread implements Runnable
{
//重寫run方法
public void run()
{
for(int i = 0; i< 30;i++)
{
System.out.println(Thread.currentThread().getName()+"..."+i);
}
}
}
//main方法如下
public static void main(String[] args) throws InterruptedException
{
JoinThread object = new JoinThread();
Thread t1 = new Thread(object);
Thread t2 = new Thread(object);
t1.start();
t1.join();
t2.start();
/**
* 主線程執行到這裏,放棄執行資格,此時活着的線程只有t1和t2,
*
* 那麼此時t1和t2交替執行,當t1執行完,主線程才能繼續執行,
* 也就是說,主線程重新獲取執行資格跟t2是否執行完沒有半毛錢關係
*
* */
//t1.join();
for(int j = 0;j < 50;j++)
{
System.out.println(Thread.currentThread().getName()+"..."+j);
}
}
上面程序運行結果 : t1執行完,t2和主線程交替執行。
注意下面細節
join()方法中如果傳入參數,則表示這樣的意思:如果A線程中掉用B線程的join(10),則表示A線程會等待B線程執行10毫秒,10毫秒過後,A、B線程並行執行。需要注意的是,jdk規定,join(0)的意思不是A線程等待B線程0秒,而是A線程等待B線程無限時間,直到B線程執行完畢,即join(0)等價於join()。
二、join()和start()調用順序問題
這樣講起來也很簡單,我們在線程start()前先把變成join()下就知道結果了。代碼就不寫了,猜想和實際一致,join()方法必須在線程start()方法調用之後調用纔有意義。一個線程都還未開始運行,同步是不具有任何意義的。
.
三、join()方法實現原理
看下源碼實現
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()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
其實,join方法是通過調用線程的wait方法來達到同步的目的的。例如,A線程中調用了B線程的join方法,則相當於A線程調用了B線程的wait方法,在調用了B線程的wait方法後,A線程就會進入阻塞狀態。
join方法的原理就是調用相應線程的wait方法進行等待操作的,例如A線程中調用了B線程的join方法,則相當於在A線程中調用了B線程的wait方法,當B線程執行完(或者到達等待時間),B線程會自動調用自身的notifyAll方法喚醒A線程,從而達到同步的目的。