繼承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的調用不會立即激活等待線程。它只是解除等待線程的阻塞狀態,這樣這些線程就可以在當前線程退出同步方法後,通過競爭獲得對對象的訪問。