最近抽空看了一下《Java多線程設計模式》這本書,書講的還是不錯的,講述的方式也很簡潔明了,讀起來很舒服。
在此記錄一些概要心得,就當讀書筆記吧
並發(Concurrent)與並行(Parallel):程式的處理不斷在各線程之間切換,一般是只有一個CPU,所以並不是同時在運行,這叫並發(Concurrent);如果具有多個CPU,則多個線程之間就可能同時運行,在某一時間點上,有多個操作在同時進行,這叫並行(Parallel)。
線程的啟動:
1)利用Thread類的子類的執行個體,啟動線程。即繼承Thread類,在子類中重寫run()方法,然後建立Thread子類的執行個體,調用start()方法。(注意,不能直接調用run方法,否則將在當前線程裡執行run方法裡的操作)。
2)定義一個實現Runnable介面的類,以這個類的執行個體作為參數建立一個Thread,然後調用該Thread執行個體的start方法。
當出去daemon線程之外的所有線程結束的時候,程式也就結束了。如果只剩下daemon線程在運行,其他的非daemon線程已經結束,則程式就會結束。daemon線程是指在建立線程時,調用setDaemon方法設定其為daemon thread的線程。
線程的暫時停止:
Thread.sleep(int msec) throws InterruptedException;
將是當前線程暫時停止運行msec毫秒。不過該方法可以通過調用interrupt方法來喚醒正在sleep的線程。
線程的共用互斥:
多個線程可能同時操作同一執行個體。Java採用關鍵字synchronized來處理共用互斥。
synchronized方法:同一執行個體的所有synchronized方法一次只能允許一個線程執行。synchronized用來表示鎖定以同步。
synchronized語句(塊):僅對後面的語句塊同步,即線程只有獲得鎖定,才能執行後面的語句塊,否則只能等待其他線程釋放鎖定。
synchronized執行個體方法:synchronized void method(){}
相當於:void method(){synchronized(this){}},也就是說synchronized執行個體方法是使用this鎖定去做線程互斥的。
synchronized類方法:class SomeClass { static synchronized void method(){…} }
相當於 class SomeClass {static void method(){synchronized(SomeClass.class){…}} },即synchronized類方法是以該類的class對象作為鎖定去同步的。
線程的協調:
object.wait(); 把當前線程放到object的wait set裡面;
object.notify(); 從object的wait set裡面喚醒一個線程;
object.notifyAll(); 喚醒所有在object的wait set裡面的線程。
所有的執行個體都有一個wait set,存放了在此執行個體上等待的線程的集合。一旦執行了wait方法,線程便會暫時停止操作,進入wait set中。當發生以下情況時,wait的線程才會退出wait set:
(1)有其他線程以notify方法喚醒該線程;(2)有其他線程以notifyAll方法喚醒該線程;(3)有其他線程以interrupt方法喚醒該線程;(4)wait方法已經到期;
線程欲執行wait和notify(或者notifyAll)方法時,必須擷取該執行個體的鎖定(否則會出異常),但是一旦因為wait方法而進入了wait set,則會馬上釋放該執行個體的鎖定。因此,被notify喚醒的線程並不是在notify的一瞬間重新開始執行,因為在notify的那一刻,執行notify的線程還握著鎖定不放,所以其他線程無法擷取該執行個體的鎖定。
線程的Interrupt——可能會花一些時間,但是可以取消掉:
需要花一點時間的方法:Object.wait(); Thread.sleep(); Thread.join(); 這些方法都throws InterruptedException,就可能會拋出異常,表明被interrupt。如果這些方法的線程被調用了interrupt方法,則會拋出InterruptedException。
Thread的執行個體方法interrupt()方法不會讓線程拋出InterruptedException,它僅僅改變了中斷狀態的值,而在sleep,join,wait方法裡判斷中斷狀態的值,來拋出異常。
Thread的執行個體方法isInterrupted方法用來檢查中斷狀態。
Thread.interrupted()類方法檢查並清除當前線程的中斷狀態。
幾個到期的方法-不建議使用:
Thread.stop(), Thread.suspend(), Thread.resume(): 這幾個方法被認為是不安全的,因為當程式處於臨界區時,暫停或者停止線程,有可能會導致死結或者不一致性。