1.sleep\wait\yield
- yiled是讓步,會使當(dāng)前線程由運(yùn)行狀態(tài)進(jìn)入到就緒狀態(tài)稠曼,讓其他優(yōu)先級高線程先執(zhí)行形病,但是如果是同一優(yōu)先級的線程,那么誰先執(zhí)行就不確定了.它不會釋放鎖霞幅。
- wailt等待漠吻,會使當(dāng)前線程進(jìn)入阻塞狀態(tài),并且會釋放鎖蝗岖。
- sleep休眠侥猩,會使當(dāng)前線程進(jìn)入休眠阻塞狀態(tài),但不會釋放鎖抵赢。
public class SleepLockTest{
private static Object obj = new Object();
public static void main(String[] args){
ThreadA t1 = new ThreadA("t1");
ThreadA t2 = new ThreadA("t2");
t1.start();
t2.start();
}
static class ThreadA extends Thread{
public ThreadA(String name){
super(name);
}
public void run(){
// 獲取obj對象的同步鎖
synchronized (obj) {
try {
for(int i=0; i <10; i++){
System.out.printf("%s: %d\n", this.getName(), i);
// i能被4整除時欺劳,休眠100毫秒
if (i%4 == 0)
Thread.sleep(100);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
2.守護(hù)線程
1.Java分為兩種線程:用戶線程和守護(hù)線程。
所謂守護(hù)線程是指在程序運(yùn)行的時候在后臺提供一種通用服務(wù)的線程铅鲤,比如垃圾回收線程就是一個很稱職的守護(hù)者划提。
這種線程并不屬于程序中不可或缺的部分,因此邢享,當(dāng)所有的非守護(hù)線程結(jié)束時鹏往,程序也就終止了,同時會殺死進(jìn)程中的所有守護(hù)線程骇塘。反過來說伊履,只要任何非守護(hù)線程還在運(yùn)行,程序就不會終止款违。
2.用戶線程和守護(hù)線程區(qū)別:
如果用戶線程已經(jīng)全部退出運(yùn)行了唐瀑,只剩下守護(hù)線程存在了,虛擬機(jī)也就退出了插爹。 因為沒有了被守護(hù)者哄辣,守護(hù)線程也就沒有工作可做了请梢,也就沒有繼續(xù)運(yùn)行程序的必要了。
3.代碼實現(xiàn)及注意事項
(1) thread.setDaemon(true)必須在thread.start()之前設(shè)置力穗,否則會跑出一個IllegalThreadStateException異常毅弧。你不能把正在運(yùn)行的常規(guī)線程設(shè)置為守護(hù)線程。
(2) 在Daemon線程中產(chǎn)生的新線程也是Daemon的当窗。
(3) 守護(hù)線程應(yīng)該永遠(yuǎn)不去訪問固有資源够坐,如文件、數(shù)據(jù)庫超全,因為它會在任何時候甚至在一個操作的中間發(fā)生中斷咆霜。
3.鎖機(jī)制
-
可重入鎖,用于實現(xiàn)同步機(jī)制。
private Lock lock = new ReentrantLock(); function(){ lock.lock(); try{...} finally{ lock.unlock(); } }
-
鎖的條件
private Condition c = lock.newCondition(); 方法(){ while(!(ok to operate)){ c.await(); } ... c.signalAll(); }
鎖和條件的注意事項
1.鎖用來保護(hù)代碼片段,任何時刻只能有一個線程執(zhí)行被保護(hù)的代碼.
2.鎖可以管理試圖進(jìn)入被保護(hù)代碼段的線程.
3.鎖可以擁有一個或多個相關(guān)的條件對象
4.每個條件對象管理那些已經(jīng)進(jìn)入被保護(hù)代碼段但還不能運(yùn)行的線程.
上述操作還可以用synchronized關(guān)鍵字和wait/notifyAll方法來完成嘶朱。
synchronized <==> lock+unlock
wait/notifyAll <==> c.await/c.signalAll
4.Lock/Condition 和 同步方法的取舍
- 最好都不用蛾坯,采用java.util.concurrent包里面提供的機(jī)制,它會為你處理所有的加鎖疏遏,例如阻塞隊列脉课。
- synchronized可以減少代碼編寫數(shù)量和出錯幾率。
- 需要Lock/Condition的獨(dú)有特性時才使用财异。
5.yield和join
1.yield
- yield是一個靜態(tài)的原生(native)方法
- yield告訴當(dāng)前正在執(zhí)行的線程把運(yùn)行機(jī)會交給線程池中擁有相同優(yōu)先級的線程倘零。
- yield不能保證使得當(dāng)前正在運(yùn)行的線程迅速轉(zhuǎn)換到可運(yùn)行的狀態(tài)
- 它僅能使一個線程從運(yùn)行狀態(tài)轉(zhuǎn)到可運(yùn)行狀態(tài),而不是等待或阻塞狀態(tài)
2.join
線程實例的方法join()方法可以使得一個線程在另一個線程結(jié)束后再執(zhí)行戳寸。如果join()方法在一個線程實例上調(diào)用呈驶,當(dāng)前運(yùn)行著的線程將阻塞直到這個線程實例完成了執(zhí)行。