線程控制基本方法 方 法 功 能 isAlive() 判斷線程是否還“活”著,即當(dāng)前run線程是否還未終止。 getPriority() 獲得線程的優(yōu)先級(jí)數(shù)值 setPriority() 設(shè)置線程的優(yōu)先級(jí)數(shù)值 Thread.sleep() 將當(dāng)前線程睡眠指定毫秒數(shù) join() 調(diào)用某線程的該方法,將當(dāng)前線程與該線程“合并”,即等待該線程結(jié)束,再恢復(fù)當(dāng)前線程的運(yùn)行。 yield() 讓出CPU,當(dāng)前線程進(jìn)入就緒隊(duì)列等待調(diào)度。 wait() 當(dāng)前線程進(jìn)入對(duì)象的wait pool。 notify()/notifyAll() 喚醒對(duì)象的wait pool中的一個(gè)/所有等待線程。 run()和start()
這兩個(gè)方法應(yīng)該都比較熟悉,把需要并行處理的代碼放在run()方法中,start()方法啟動(dòng)線程將自動(dòng)調(diào)用 run()方法,這是由Java的內(nèi)存機(jī)制規(guī)定的。并且run()方法必須是public訪問權(quán)限,返回值類型為void。 isAlive方法實(shí)例:
interrupt/sleep方法: 可以調(diào)用Thread的靜態(tài)方法: public static void sleep(long millis) throws InterruptedException 使得當(dāng)前線程休眠(暫時(shí)停止執(zhí)行millis毫秒)。 由于是靜態(tài)方法,sleep可以由類名直接調(diào)用:Thread.sleep(…)
使當(dāng)前線程(即調(diào)用該方法的線程)暫停執(zhí)行一段時(shí)間,讓其他線程有機(jī)會(huì)繼續(xù)執(zhí)行,但它并不釋放對(duì)象鎖。也就是如果有Synchronized同步塊,其他線程仍然不同訪問共享數(shù)據(jù)。注意該方法要捕獲異常
比如有兩個(gè)線程同時(shí)執(zhí)行(沒有Synchronized),一個(gè)線程優(yōu)先級(jí)為MAX_PRIORITY,另一個(gè)為MIN_PRIORITY,如果沒有 Sleep()方法,只有高優(yōu)先級(jí)的線程執(zhí)行完成后,低優(yōu)先級(jí)的線程才能執(zhí)行;但當(dāng)高優(yōu)先級(jí)的線程sleep(5000)后,低優(yōu)先級(jí)就有機(jī)會(huì)執(zhí)行了。
總之,sleep()可以使低優(yōu)先級(jí)的線程得到執(zhí)行的機(jī)會(huì),當(dāng)然也可以讓同優(yōu)先級(jí)、高優(yōu)先級(jí)的線程有執(zhí)行的機(jī)會(huì)。
停止線程的方法中,stop最強(qiáng)暴,其次便是interrupte,這兩種都是不提倡的,推薦的方法是通過flag標(biāo)志來終止線程,例如:
join方法: 合并某個(gè)線程,,join()方法使調(diào)用該方法的線程在此之前執(zhí)行完畢,也就是等待調(diào)用該方法的線程執(zhí)行完畢后再往下繼續(xù)執(zhí)行。注意該方法也要捕獲異常。
yield方法: 暫時(shí)讓出CPU,給其他線程執(zhí)行的機(jī)會(huì),它與sleep()類似,只是不能由用戶指定暫停多長時(shí)間,并且yield()方法只能讓同優(yōu)先級(jí)的線程有執(zhí)行的機(jī)會(huì)。
setPriority():
關(guān)鍵字Synchronized
這個(gè)關(guān)鍵字用于保護(hù)共享數(shù)據(jù),當(dāng)然前提是要分清哪些數(shù)據(jù)是共享數(shù)據(jù)。每個(gè)對(duì)象都有一個(gè)鎖標(biāo)志,當(dāng)一個(gè)線程訪問該對(duì)象時(shí),被Synchronized修飾的數(shù)據(jù)將被“上鎖”,阻止其他線程訪問。當(dāng)前線程訪問完這部分?jǐn)?shù)據(jù)后釋放鎖標(biāo)志,其他線程就可以訪問了。
注意以下這個(gè)例子
結(jié)果: 0 0 1 2 3 4 1 5 2 6 3 7 4 8 9 5 6 7 8 9 ;(不同對(duì)象) 以上這段程序中的 i 變量并不是共享數(shù)據(jù),這個(gè)程序中的t1,t2分別是兩個(gè)對(duì)象(r1,r2)的線程。JAVA是面向?qū)ο蟮某绦蛟O(shè)計(jì)語言,不同的對(duì)象的數(shù)據(jù)是不同的,r1,r2有各自的run()方法,而synchronized使同一個(gè)對(duì)象的多個(gè)線程,在某個(gè)時(shí)刻只有其中的一個(gè)線程可以訪問這個(gè)對(duì)象的synchronized數(shù)據(jù)。
當(dāng)把代碼改成如下:Synchronized關(guān)鍵字才會(huì)起作用
Runnable r = new ThreadTest();
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
t1.start();
t2.start();
synchronized 導(dǎo)致的死鎖問題:
wait()和notify()、notifyAll()
這三個(gè)方法用于協(xié)調(diào)多個(gè)線程對(duì)共享數(shù)據(jù)的存取,所以必須在Synchronized語句塊內(nèi)使用這三個(gè)方法。前面說過Synchronized這個(gè)關(guān)鍵字用于保護(hù)共享數(shù)據(jù),阻止其他線程對(duì)共享數(shù)據(jù)的存取。但是這樣程序的流程就很不靈活了,如何才能在當(dāng)前線程還沒退出Synchronized數(shù)據(jù)塊時(shí)讓其他線程也有機(jī)會(huì)訪問共享數(shù)據(jù)呢?此時(shí)就用這三個(gè)方法來靈活控制。
wait()方法使當(dāng)前線程暫停執(zhí)行并釋放對(duì)象鎖標(biāo)志,讓其他線程可以進(jìn)入Synchronized數(shù)據(jù)塊,當(dāng)前線程被放入對(duì)象等待池中。當(dāng)調(diào)用 notify()方法后,將從對(duì)象的等待池中移走一個(gè)任意的線程并放到鎖標(biāo)志等待池中,只有
鎖標(biāo)志等待池中的線程能夠獲取鎖標(biāo)志;如果鎖標(biāo)志等待池中沒有線程,則notify()不起作用。
notifyAll()則從對(duì)象等待池中移走所有等待那個(gè)對(duì)象的線程并放到鎖標(biāo)志等待池中。
注意 這三個(gè)方法都是java.lang.Ojbect的方法!
Powered by: BlogJava Copyright © Gavin.lee