1. 程式人生 > >好讀書不求甚解(一)Java多執行緒程式設計核心技術

好讀書不求甚解(一)Java多執行緒程式設計核心技術

看書經常看過後就沒多少印象了,決定把看的做個簡單記錄或者摘要,用於加深印象.
書封面

第1章 Java多執行緒技能

1) 實現多執行緒變成的方式主要兩種,一種是繼承Thread類,一種是實現Runnable介面
2) currentThread()方法,返回程式碼段正在被哪個執行緒呼叫.要注意Thread.currentThread()和this的區別
3) isAlive()方法,判斷當前執行緒是否處於活動狀態.活動狀態指執行緒已經啟動且尚未終止
4) sleep()方法,當前正在執行的執行緒休眠指定時間,不釋放鎖
5) 停止執行緒的方法,正常停止(執行結束),stop方法(已廢棄),interrupt方法
6) interrupted(),靜態方法,測試當前執行緒是否已經中斷,並清除中斷標識
7) isInterrupted(),例項方法,測試執行緒是否已經中斷,不清除中斷標識
8) sleep的執行緒也可以停止(需要捕獲異常)
9) yield()方法,讓出CPU給其他執行緒,也可能讓出後自己又搶到
10) 執行緒優先順序,儘量不使用
11) 守護執行緒,java執行緒分兩種,使用者執行緒,守護執行緒.程序中沒有使用者執行緒後,守護執行緒自動銷燬

第2章 物件及變數的併發訪問

2.1 synchronized同步方法

1)方法內變數為執行緒安全(在棧上)
2)例項變數非執行緒安全(在堆上)
3)synchronized方法是鎖定的例項物件,多個例項不互斥
4)鎖可重入
5)出現異常,自動釋放鎖

2.2 synchronized同步程式碼塊

1) 同步程式碼塊通過減少同步的範圍,來提高效率
2) synchronized() 引數如果不一個,則是非同步
3) synchronized(class)鎖定class物件=synchronized static方法
4) synchronized程式碼塊儘量別用String作為鎖物件

2.3 volatile

1) volatile修飾的變數具有可見性.即執行緒使用時都要從主記憶體讀取.
2) volatile不具備原子性
3) 結合1,2兩點, volatile適合只有一個執行緒修改資料,或者像一個執行緒修改flag=false,別的執行緒都停止這種.
4) 原子類也並不完全安全(方法間不同步),類似Hashtable

第3章 執行緒間通訊

3.1 等待/通知機制

1) wait()方法使當前執行程式碼的執行緒進行等待.會立即釋放鎖
2) notify()方法通知呈wait狀態且等待這個鎖的執行緒,如果多個則隨機通知一個.會釋放鎖,但不是立即,要等同步區域內程式碼執行完成
3) notifyAll()方法通知呈wait狀態且等待這個鎖的全部執行緒,釋放鎖和notify方法一樣
4) 上面1,2,3都會釋放鎖,所以執行前都需要已經獲得鎖
5) sleep()方法不釋放鎖
6) wait()的執行緒,呼叫interrupt()方法會丟擲InterruptedException
7) wait(long)是long時間內沒有被喚醒的話,則自動被喚醒
8) 多生產者,多消費者 如果使用notify可能喚醒的是同類,可能出現假死情況.使用notifyAll來解決
9) 可以使用PipeInputStream,PipedOutputStream,PipedReader,PipedWriter實現執行緒間通訊

3.2 join方法

1) join()的作用是使所屬的執行緒物件x正常秩序run()中的任務,而使當前執行緒z阻塞到執行緒x銷燬後再執行
2) join()是使用wait()方法實現的,synchronized是使用的"物件監視器"
3) 啟動執行緒b,b中啟動執行緒a,然後a.join(),如果b.interrupt(),則b丟擲異常,a正常執行
4) join(long)比起join()多了個阻塞的時間,和sleep(long)的區別是join會釋放鎖(因為是用wait實現的)

3.3 ThreadLocal類

1) 各執行緒可以用ThreadLocal來存放私有資料.set()設定,get()返回(為什麼不弄個map那樣子的呢,呵呵)
2) get()的初始化值,可以通過extends ThreadLocal,override initialValue()實現

第4章 Lock的使用

4.1 ReentrantLock類

1) synchronized結合wait(),notify(),notifyAll()可以實現等待/通知模式,ReentrantLock藉助Condition物件實現等待/通知模式
2) 使用notify()被通知的執行緒是JVM隨機選的,Condition類可以自己選擇
3) Object.wait()相當於Condition.await(),Object.notify()相當於 Condition.signal()
4) await()和signal()方法使用前需要獲得鎖
5) new ReentrantLock(boolean isFair) 可以指定是否為公平鎖,不過公平鎖也不是絕對公平的
6) 以下7-9是ReentrantLock類的一些方法說明
7) getHoldCount()返回呼叫lock()的次數,getQueueLength()返回正等待獲取此鎖的執行緒估計數,getWaitQueueLength(condition)返回正等待獲取此鎖此條件的執行緒估計數
8) hasQueuedTread(Thread thread)返回指定執行緒是否正在等待獲取此鎖,hasQueuedThreads()返回是否有執行緒正在等待獲取此鎖,hasWaiters(condition)返回是否有執行緒正在等待此鎖此條件
9) isFair()返回是否公平鎖,isHeldByCurrentThread()返回當前執行緒是否持有此鎖,isLocked()返回此鎖是否由任意執行緒持有

4.2 ReentrantReadWriteLock類

1) 讀讀共享,讀寫互斥,寫寫互斥,寫讀互斥

第5章 定時器Timer

書裡只是講了怎麼使用,可以直接去看API文件,而且現在專案開發一般都使用封裝過的spring task或者quartz,所以這裡就不記錄了

第6章 單例模式與多執行緒

1) 在部落格 http://blog.csdn.net/qq315737546/article/details/29387381 中對單例模式有過說明
2) 最好使用列舉來實現單例,可以用class再包裝一層(6.7的例子)

第7章 拾遺增補

1) Thread.State 列舉中,列出了執行緒的所有狀態,並有解釋

API
2) 執行緒狀態通過有關方法進行切換,有些切換是單向的
3) 可以把執行緒歸屬到某一個執行緒組中,統一管理
4) SimpleDateFormat是非執行緒安全的
5) 執行緒異常可以通過UncaughtExceptionHandler進行捕獲.可以setDefaultUcaughtExceptionHandler()設定預設的異常處理器
6) 預設情況下,執行緒組中一個執行緒出現異常不會影響其他執行緒,可以通過自定義執行緒組+重寫uncaughtException()方法來停止組內所有執行緒
7) 執行緒異常處理 thread.setUncaughtExceptionHandler()>Thread.setDefaultUncaughtExceptionHandler()>執行緒組的異常處理

內容總結

1.  使用synchronized(同步方法,同步程式碼塊),lock的時候,重點在於知道他們使用的物件監視器是否一個(即加鎖的物件)
2.  lock比synchronized更強大,更靈活

不好的地方

1.  書裡大部分例子都是用的XX extend Thread來實現, 這種實現可以直接呼叫XX例項xx.start()方法執行即可.不需要再Thread t = new Thread(xx), 我認為實現Runnable方式這樣寫更合適.(Thread類本身也實現了Runnable介面.....)
2.  有些地方有結論,有程式碼,但是沒有說明,搞的有點不理解
3.  有些地方只有程式碼... 更難理解

好的地方

1.  程式碼示例很多,觀點都通過程式碼去證明
2.  很多時候,對一些知識點不知道怎麼去驗證,這本書能加強舉例子的能力