日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java方法中 thread,Java中的線程Thread方法之---join()

發布時間:2025/3/19 java 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java方法中 thread,Java中的線程Thread方法之---join() 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

上一篇我們說到了Thread中的stop方法,這一篇我們再來看一下方法join的使用,那么方法Join是干啥用的? 簡單回答,同步,如何同步? 怎么實現的? 下面將逐個回答。

join方法從字面上的意思就是加入到一個線程中,這樣就可以很好的進行線程之間的交互運行了,不多說先來看一下代碼:

package com.threadjoin.demo;

public class ThreadJoin {

public static int a = 0;

public static void main(String[] args){

Thread thread = new Thread(new Runnable(){

@Override

public void run(){

for(int i=0;i<5;i++)

a++;

}

});

thread.start();

/*try {

thread.join();

} catch (InterruptedException e) {

e.printStackTrace();

}*/

System.out.println(a);

}

}

運行代碼,貌似永遠都看不到a的值是5,而每次都是0,原因很簡單的,因為在thread中的run方法中進行a的增值操作,這些可能都是需要時間的,但是此時main線程中的System.out.println方法已經執行了,所以很難看到a的值是5,為了看到a的值是5,我的一個思路就是等thread運行結束之后,我們采取執行System.out.println就可以了,這時候join方法的作用就顯現出來的,我們把上面的注釋代碼刪除注釋,然后運行,不管運行多少次,輸出的結果都是5,從這個例子中我們就可以看到join方法的作用,它能夠調節各個線程之間的運行順序,從而可以實現同步。為了更好的了解join的運行原理我們只有看他的源碼了:

publicfinalvoidjoin()throwsInterruptedException?{

join(0);

}

我們在跟蹤到join(0)方法中:

//方法是個同步的,而且會拋出InterruptedException異常

publicfinalsynchronizedvoidjoin(longmillis)throwsInterruptedException?{

longbase?=?System.currentTimeMillis();

longnow?=0;

if(millis?<0)?{

thrownewIllegalArgumentException("timeout?value?is?negative");

}

//我們可以看到這里使用了while循環做判斷的,然后調用wait方法的,所以說join方法的執行是完全通過wait方法實現的

//等待時間為0的時候,就是無限等待,直到線程死亡了(即線程執行完了)

if(millis?==0)?{

//如果當前線程還存活的話,就等待

while(isAlive())?{

//調用該線程的join方法的線程拿到鎖之后進行等待,直到線程執行結束(這個例子就是main線程)

wait(0);

}

}?else{

//如果是等待的特定時間的話

while(isAlive())?{

longdelay?=?millis?-?now;

if(delay?<=0)?{

break;

}

wait(delay);

now?=?System.currentTimeMillis()?-?base;

}

}

}

從代碼中我們可以看到join方法是個同步的,這個我們后面會做個例子,然后進入到方法中我們可以看到,有兩種情況,一種是等待時間是0的,其實就等同無線等待,直到線程執行結束了,還有一種就是要等待的是一定的時間,原理都是一樣的,

看完源碼之后我們在看一一個例子:

packagecom.threadjoin.demo;

/**

*

其實Join方法實現是通過wait(小提示:Object?提供的方法)。

當main線程調用t.join時候,main線程會獲得線程對象t的鎖(wait意味著拿到該對象的鎖),

調用該對象的wait(等待時間),直到該對象喚醒main線程,比如退出后。

這就意味著main?線程調用t.join時,

必須能夠拿到線程t對象的鎖,如果拿不到它是無法wait的,剛開的例子t.join(1000)不是說明了main線程等待1秒,

如果在它等待之前,其他線程獲取了t對象的鎖,它等待時間可不就是1秒了

*?@author?weijiang204321

*

*/

publicclassThreadJoinTest?{

publicstaticvoidmain(String[]?args)?{

Thread?t?=?newThread(newRunnableImpl());

newThreadTest(t).start();

t.start();

try{

t.join(1000);

System.out.println("joinFinish");

}?catch(InterruptedException?e)?{

e.printStackTrace();

}

}

}

classRunnableImplimplementsRunnable?{

@Override

publicvoidrun()?{

try{

System.out.println("Begin?sleep");

Thread.sleep(1000);

System.out.println("End?sleep");

}?catch(InterruptedException?e)?{

e.printStackTrace();

}

}

}

classThreadTestextendsThread?{

Thread?thread;

publicThreadTest(Thread?thread)?{

this.thread?=?thread;

}

@Override

publicvoidrun()?{

holdThreadLock();

}

publicvoidholdThreadLock()?{

//用當前的線程當做lock

synchronized(thread)?{

System.out.println("getObjectLock");

try{

Thread.sleep(9*1000);

}?catch(InterruptedException?ex)?{

ex.printStackTrace();

}

System.out.println("ReleaseObjectLock");

}

}

}

在main方法中通過new??ThreadTest(t).start()實例化?ThreadTest?線程對象, 它?通過?synchronized??(thread)?,獲取線程對象t的鎖,並sleep(9*1000)后釋放,因為我們上面看到了join方法是個同步的,而且同步鎖是當前的線程對象,因為ThreadTest先運行的,首先拿到了線程t對象的鎖,所以join方法還沒有拿到鎖,所以要等待。這就意味著,即使main方法t.join(1000)等待一秒鍾,它必須等待ThreadTest?線程釋放t鎖后才能進入wait方法中,它實際等待時間是9000+1000ms=10s。

總結

以上是生活随笔為你收集整理的java方法中 thread,Java中的線程Thread方法之---join()的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。