JAVA多線程 JOIN
十載的象山網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開(kāi)發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。成都營(yíng)銷網(wǎng)站建設(shè)的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整象山建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無(wú)論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。成都創(chuàng)新互聯(lián)從事“象山網(wǎng)站設(shè)計(jì)”,“象山網(wǎng)站推廣”以來(lái),每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
對(duì)于Java開(kāi)發(fā)人員,多線程應(yīng)該是必須熟練應(yīng)用的知識(shí)點(diǎn),特別是開(kāi)發(fā)基于Java語(yǔ)言的產(chǎn)品。本文將深入淺出的表述Java多線程的知識(shí)點(diǎn),在后續(xù)的系列里將側(cè)重于Java5由Doug Lea教授提供的Concurrent并行包的設(shè)計(jì)思想以及具體實(shí)現(xiàn)與應(yīng)用。
如何才能深入淺出呢,我的理解是帶著問(wèn)題,而不是泛泛的看。所以該系列基本以解決問(wèn)題為主,當(dāng)然我也非常希望讀者能夠提出更好的解決問(wèn)題的方案以及提出更多的問(wèn)題。由于水平有限,如果有什么錯(cuò)誤之處,請(qǐng)大家提出,共同討論,總之,我希望通過(guò)該系列我們能夠深入理解Java多線程來(lái)解決我們實(shí)際開(kāi)發(fā)的問(wèn)題。
作為開(kāi)發(fā)人員,我想沒(méi)有必要討論多線程的基礎(chǔ)知識(shí),比如什么是線程? 如何創(chuàng)建等 ,這些知識(shí)點(diǎn)是可以通過(guò)書本和Google獲得的。本系列主要是如何理深入解多線程來(lái)幫助我們平時(shí)的開(kāi)發(fā),比如線程池如何實(shí)現(xiàn)? 如何應(yīng)用鎖等。
(1)方法Join是干啥用的? 簡(jiǎn)單回答,同步,如何同步? 怎么實(shí)現(xiàn)的? 下面將逐個(gè)回答。
自從接觸Java多線程,一直對(duì)Join理解不了。JDK是這樣說(shuō)的:
join public final void join(long millis)throws InterruptedException Waits at most millis milliseconds for this thread to die. A timeout of 0 means to wait forever.
大家能理解嗎? 字面意思是等待一段時(shí)間直到這個(gè)線程死亡,我的疑問(wèn)是那個(gè)線程,是它本身的線程還是調(diào)用它的線程的,上代碼:
package concurrentstudy; /** * * @author vma */ public class JoinTest { public static void main(String[] args) { Thread t = new Thread(new RunnableImpl()); t.start(); try { t.join(1000); System.out.println("joinFinish"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } class RunnableImpl implements Runnable { @Override public void run() { try { System.out.println("Begin sleep"); Thread.sleep(1000); System.out.println("End sleep"); } catch (InterruptedException e) { e.printStackTrace(); } } }
結(jié)果是:
Begin sleep End sleep joinFinish
明白了吧,當(dāng)main線程調(diào)用t.join時(shí),main線程等待t線程,等待時(shí)間是1000,如果t線程Sleep 2000呢
public void run() { try { System.out.println("Begin sleep"); // Thread.sleep(1000); Thread.sleep(2000); System.out.println("End sleep"); } catch (InterruptedException e) { e.printStackTrace(); } }
結(jié)果是:
Begin sleep joinFinish End sleep
也就是說(shuō)main線程只等1000毫秒,不管T什么時(shí)候結(jié)束,如果是t.join()呢, 看代碼:
public final void join() throws InterruptedException { join(0); }
就是說(shuō)如果是t.join() = t.join(0) 0 JDK這樣說(shuō)的 A timeout of 0 means to wait forever 字面意思是永遠(yuǎn)等待,是這樣嗎?
其實(shí)是等到t結(jié)束后。
這個(gè)是怎么實(shí)現(xiàn)的嗎? 看JDK代碼:
/** * Waits at most <code>millis</code> milliseconds for this thread to * die. A timeout of <code>0</code> means to wait forever. * * @param millis the time to wait in milliseconds. * @exception InterruptedException if any thread has interrupted * the current thread. The <i>interrupted status</i> of the * current thread is cleared when this exception is thrown. */ 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; } } }
其實(shí)Join方法實(shí)現(xiàn)是通過(guò)wait(小提示:Object 提供的方法)。 當(dāng)main線程調(diào)用t.join時(shí)候,main線程會(huì)獲得線程對(duì)象t的鎖(wait 意味著拿到該對(duì)象的鎖),調(diào)用該對(duì)象的wait(等待時(shí)間),直到該對(duì)象喚醒main線程,比如退出后。
這就意味著main 線程調(diào)用t.join時(shí),必須能夠拿到線程t對(duì)象的鎖,如果拿不到它是無(wú)法wait的,剛開(kāi)的例子t.join(1000)不是說(shuō)明了main線程等待1秒,如果在它等待之前,其他線程獲取了t對(duì)象的鎖,它等待時(shí)間可不就是1毫秒了。上代碼介紹:
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package concurrentstudy; /** * * @author vma */ public class JoinTest { public static void main(String[] args) { Thread t = new Thread(new RunnableImpl()); new ThreadTest(t).start(); t.start(); try { t.join(); System.out.println("joinFinish"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } class ThreadTest extends Thread { Thread thread; public ThreadTest(Thread thread) { this.thread = thread; } @Override public void run() { holdThreadLock(); } public void holdThreadLock() { synchronized (thread) { System.out.println("getObjectLock"); try { Thread.sleep(9000); } catch (InterruptedException ex) { ex.printStackTrace(); } System.out.println("ReleaseObjectLock"); } } } class RunnableImpl implements Runnable { @Override public void run() { try { System.out.println("Begin sleep"); Thread.sleep(2000); System.out.println("End sleep"); } catch (InterruptedException e) { e.printStackTrace(); } } }
在main方法中 通過(guò)new ThreadTest(t).start();實(shí)例化ThreadTest 線程對(duì)象, 它在holdThreadLock()方法中,通過(guò)synchronized (thread),獲取線程對(duì)象t的鎖,并Sleep(9000)后釋放,這就意味著,即使main方法t.join(1000),等待一秒鐘,它必須等待ThreadTest 線程釋放t鎖后才能進(jìn)入wait方法中,它實(shí)際等待時(shí)間是9000+1000 MS
運(yùn)行結(jié)果是:
getObjectLock Begin sleep End sleep ReleaseObjectLock joinFinish
小結(jié):
本節(jié)主要深入淺出join及JDK中的實(shí)現(xiàn)。
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
網(wǎng)站題目:JAVA多線程之方法JOIN詳解及實(shí)例代碼
分享鏈接:http://bm7419.com/article8/igddip.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁(yè)設(shè)計(jì)公司、網(wǎng)站營(yíng)銷、品牌網(wǎng)站建設(shè)、動(dòng)態(tài)網(wǎng)站、品牌網(wǎng)站制作、網(wǎng)站收錄
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)