多線程學習筆記(一)

繼承Thread類來封裝要同步內容

class TestThread extends Thread{ 

void run(){ 處理內容。。。 }

}

// 實現Runnable來實現並封裝要同步內容

class TestRunnable implements Runnable{

 public void run(){ 處理內容。。。 } 

}

public class StartRunnable{

 public static void main(String[] args){

  new Thread(new TestRunnable()).start(); 

}

}

//取得當前線程,並判斷當前線程是否被中斷的。

if(Thread.currentThread().isInterrupted()){ 處理內容。。。}

 //中斷線程new TestThread().iterrupt();

如果一個線程被阻塞了,它就無法檢查中斷狀態了。這就是產生IterruptedException異常的地方。當在一個被阻塞的線程上調用interrupt方法時,阻塞調用(例如Sleep或者wait)就會被 InterruptedException異常所終止。中斷線程不一定要終止線程,不同的線程對中斷有不同的處理方法。

interrupted()方法和isInterrupted()的比較:

interrupted()方法:測試當前線程是否已經中斷。線程的中斷狀態 由該方法清除。換句話說,如果連續兩次調用該方法,則第二次調用將返回 false。

isInterrupted()方法:測試線程是否已經中斷。線程的中斷狀態 不受該方法的影響。

 1.3 線程狀態

New:新生

Runnable:可運行

Blocked:被阻塞

Dead:死亡

1.3.1 新生狀態         

 new Thread();

1.3.2 可運行線程          new Thread().start();    

      這個狀態線程不一定時在執行的,也可以處於不執行狀態,因爲這是有操作系統來安排這個運行時間。記住,這個使Runnable,而不是Running!!!         

 搶佔式調度:系統給每個可運行的線程一個時間片來處理任務。當這個時間片用完時,操作系統剝奪該線程對資源的佔用,使其他線程有機會運行。現代操作系統都使用這個調度機制。

1.3.3 被阻塞線程         

當發生一下任何一種情況時,線程就進入被阻塞狀態:         

1)調用 Sleep方法         

2)線程調用一個在i/o上被阻塞的操作,即這個i/o操作結束之前不會返回到它的調用着         

 3)線程試圖獲得鎖,而這個鎖被其他線程佔有         

當一個線程被阻塞時候,另一個線程就可以被調度運行了。當一個被阻塞線程重新被激活時,調度起檢查它的優先級有沒有比當前正在執行的線程優先級高不高,假如高,它就將搶佔當前線程的資源,並開始運行。          

通過一下方式線程可以從被阻塞狀態回到可運行狀態。        

1)Sleep的毫秒數已過時        

2)線程正在等待的i/o操作已經完成時        

3)線程正在等待另一個現成所持有的鎖,且另一個線程已經釋放該鎖        

4)線程正在等待某個出發條件,且另一個線程發出了信號表明條件已經發生了變化。被超時時候也 包括       

5)線程已被掛起,且有人調用它的resume方法。但這個已經被棄用  

1.3.4 死線程      導致死線程的原因如下:     

1)run方法正常退出     

 2)因爲一個未捕獲的異常中止了run方法而使線程死亡      

isAalive方法:     

測試線程是否處於活動狀態(要麼是可運行的,要麼是被阻塞的)。如果線程已經啓動且尚未終止,則爲活動狀態。     

join(long millis)方法:     

等待該線程終止的時間最長爲 millis 毫秒。超時爲 0 意味着要一直等下去。

1.4 線程優先級    

線程級別:    

Thread.MIN_PRIORITY : 1    

Thread.MAX_PRIORITY : 10    

Thread.NORM_PRIORITY :5         

public final void setPriority(int newPriority)方法:    

 更改線程的優先級。     

public final int getPriority()方法:   

返回線程的優先級。       

public static void yield()方法:  

暫停當前正在執行的線程對象,並執行其他線程。

1.4.2 守護線程(後臺線程)       

public final void setDaemon(boolean on)方法:       

setDeamon(true);設置爲守護線程

1.4.3 線程組         

ThreadGroup g = new ThreadGroup(groupName);//groupName是唯一的。         

 Thread t = new Thread(g , threadName);          

public int activeCount()方法:         

返回此線程組中活動線程的估計數。                   

public final void interrupt()方法:        

中斷此線程組中的所有線程。        

new Thread().getThreadGroup()方法:        

返回該線程所屬的線程組。 如果該線程已經終止(停止運行),該方法則返回 null。

1.5  同步 

1.5.3 鎖對象     

jdk5.0引進的ReentrantLock類      

 public void lock()方法:     

獲取鎖。     

public void unlock()方法:     

試圖釋放此鎖。1.5.4  條件對象     

Condition c = new ReentrantLock().newCondition();     

c.await();/

/造成當前線程在接到信號或被中斷之前一直處於等待狀態。      

c.signalAll();

//喚醒所有等待線程。       

當一個線程調用了await時,它無法自己解除阻塞狀態。它把自己的命運交給了其他線程。如果沒有任何其他的線程來接觸等待線程的阻塞狀態,它就永遠也不會運行了,這會導致死鎖。    那麼應該什麼時候調用signalAall呢?例如,當一個賬戶餘額發生變化時,等待線程應該有機會去檢查餘額。這樣使正在因爲餘額不足而被阻塞的線程去嘗試一下條件滿不滿足。    signalAll的調用不會立即激活等待線程。它只是解除等待線程的阻塞狀態,這樣這些線程就可以在當前線程退出同步方法後,通過競爭獲得對對象的訪問。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章