2015年機械工業出版社出版社出版程曉明,方騰飛,魏鵬編著圖書。
基本介紹
- 中文名稱:Java並發編程的藝術
- 裝幀:平裝
- 定價:59.00元
- 作者:程曉明,方騰飛,魏鵬
- 出版社:機械工業出版社
- 出版日期:2015-7-1
- ISBN:9787111508243
編輯推薦,作者簡介,目錄,文摘,
編輯推薦
《Java並發編程的藝術》正是為了解決這個問題而寫的。書中採用循序漸進的講解方式,從並發編程的底層實現機制入手,逐步介紹了在設計Java並發程式時各種重要的技術、設計模式與套用,同時輔以豐富的示例代碼,使得開發人員能夠更快地領悟Java並發編程的要領,圍繞著Java平台的基礎並發功能快速地構建大規模的並發應用程式。
作者簡介
方騰飛(花名清英,英文名kral),螞蟻金服集團技術專家,從事Java開發近10年。5年以上的團隊管理、項目管理和敏捷開發經驗,崇尚團隊合作。曾參與CMS、電子海圖、SOC、ITIL、電子商務網站和信貸管理系統等項目。目前在螞蟻金服網商銀行貸款管理團隊負責數據採集平台開發工作。與同事合作開發了tala code Review外掛程式,深受阿里數千名工程師擁躉,並開發過開源工具jdbcutil(https://github.com/kiral/utils)。創辦了並發編程網(http://ifeve.com),組織翻譯了百餘篇國外優秀技術文章,並曾為InfoQ撰寫“聊聊並發”專欄,在《程式設計師》雜誌撰寫敏捷實踐系列文章,曾用部落格http://kiraljavaeye.com。
魏鵬,阿里巴巴集團技術專家,在阿里巴巴中國網站技術部工作多年,曾擔任中國網站交易平台架構師,主導了交易系統服務化工作,設計實現的數據遷移系統高效地完成了阿里巴巴中國網站交易數據到阿里巴巴集團的遷移工作。目前在阿里巴巴共享業務事業部從事Java套用容器Pandora和服務框架HSF的相關工作,其中Java套用容器Pandora是阿里巴巴中間件運行的基礎,而服務框架HSF則是阿里巴巴集團實現服務化的主要解決方案,二者在阿里巴巴擁有最為廣泛的使用量。個人平時喜歡閱讀技術書籍,翻譯一些國外優秀文檔,喜歡總結、樂於分享,對Java套用容器、多執行緒編程以及分散式系統感興趣。
程曉明,1號店資深架構師,從事1號店交易平台系統的開發,技術上關注並發與NIO。因5年前遇到的一個線上故障,解決過程中對Java並發編程產生了濃厚的興趣,從此開始了漫長的探索之旅:從底層實現機制、記憶體模型到Java同步。縱觀我自己對Java並發的學習過程.是一個從高層到底層再到高層的一個反覆疊代的過程,我估計很多讀者的學習過程應該與我類似。文章多見諸《IBM developer Works》、InfoQ和《程式設計師》雜誌。
目錄
前言
第1章並發編程的挑戰1
1.1上下文切換1
1.1.1多執行緒一定快嗎1
1.1.2測試上下文切換次數和時長3
1.1.3如何減少上下文切換3
1.1.4減少上下文切換實戰4
1.2死鎖5
1.3資源限制的挑戰6
1.4本章小結7
第2章Java並發機制的底層實現原理8
2.1volatile的套用8
2.2synchronized的實現原理與套用11
2.2.1Java對象頭12
2.2.2鎖的升級與對比13
2.3原子操作的實現原理16
2.4本章小結20
第3章Java記憶體模型21
3.1Java記憶體模型的基礎21
3.1.1並發編程模型的兩個關鍵問題21
3.1.2Java記憶體模型的抽象結構22
3.1.3從原始碼到指令序列的重排序23
3.1.4並發編程模型的分類24
3.1.5happens—before簡介26
3.2重排序27
3.2.1數據依賴性28
3.2.2as—if—serial語義28
3.2.3程式順序規則29
3.2.4重排序對多執行緒的影響29
3.3順序一致性31
3.3.1數據競爭與順序一致性31
3.3.2順序一致性記憶體模型32
3.3.3同步程式的順序一致性效果34
3.3.4未同步程式的執行特性35
3.4volatile的記憶體語義38
3.4.1volatile的特性38
3.4.2volatile寫—讀建立的happens—before關係39
3.4.3volatile寫—讀的記憶體語義40
3.4.4volatile記憶體語義的實現42
3.4.5JSR—133為什麼要增強volatile的記憶體語義46
3.5鎖的記憶體語義47
3.5.1鎖的釋放—獲取建立的
happens—before關係47
3.5.2鎖的釋放和獲取的記憶體語義48
3.5.3鎖記憶體語義的實現50
3.5.4concurrent包的實現54
3.6final域的記憶體語義55
3.6.1final域的重排序規則55
3.6.2寫final域的重排序規則56
3.6.3讀final域的重排序規則57
3.6.4final域為引用類型58
3.6.5為什麼final引用不能從構造函式內“溢出”59
3.6.6final語義在處理器中的實現61
3.6.7JSR—133為什麼要增強f?inal的語義62
3.7happens—before62
3.7.1JMM的設計62
3.7.2happens—before的定義64
3.7.3happens—before規則65
3.8雙重檢查鎖定與延遲初始化67
3.8.1雙重檢查鎖定的由來67
3.8.2問題的根源69
3.8.3基於volatile的解決方案71
3.8.4基於類初始化的解決方案72
3.9Java記憶體模型綜述78
3.9.1處理器的記憶體模型78
3.9.2各種記憶體模型之間的關係80
3.9.3JMM的記憶體可見性保證80
3.9.4JSR—133對舊記憶體模型的修補81
3.10本章小結82
第4章Java並發編程基礎83
4.1執行緒簡介83
4.1.1什麼是執行緒83
4.1.2為什麼要使用多執行緒84
4.1.3執行緒優先權85
4.1.4執行緒的狀態87
4.1.5Daemon執行緒90
4.2啟動和終止執行緒91
4.2.1構造執行緒91
4.2.2啟動執行緒92
4.2.3理解中斷92
4.2.4過期的suspend()、resume()和stop()93
4.2.5安全地終止執行緒95
4.3執行緒間通信96
4.3.1volatile和synchronized關鍵字96
4.3.2等待/通知機制98
4.3.3等待/通知的經典範式101
4.3.4管道輸入/輸出流102
4.3.5Thread.join()的使用103
4.3.6ThreadLocal的使用105
4.4執行緒套用實例106
4.4.1等待逾時模式106
4.4.2一個簡單的資料庫連線池示例106
4.4.3執行緒池技術及其示例110
4.4.4一個基於執行緒池技術的簡單Web伺服器114
4.5本章小結118
第5章Java中的鎖119
5.1Lock接口119
5.2佇列同步器121
5.2.1佇列同步器的接口與示例121
5.2.2佇列同步器的實現分析124
5.3重入鎖136
5.4讀寫鎖140
5.4.1讀寫鎖的接口與示例141
5.4.2讀寫鎖的實現分析142
5.5LockSupport工具146
5.6Condition接口147
5.6.1Condition接口與示例148
5.6.2Condition的實現分析150
5.7本章小結154
第6章Java並發容器和框架155
6.1ConcurrentHashMap的實現原理與使用155
6.1.1為什麼要使用ConcurrentHashMap155
6.1.2ConcurrentHashMap的結構156
6.1.3ConcurrentHashMap的初始化157
6.1.4定位Segment159
6.1.5ConcurrentHashMap的操作160
6.2ConcurrentLinkedQueue161
6.2.1ConcurrentLinkedQueue的結構162
6.2.2入佇列162
6.2.3出佇列165
6.3Java中的阻塞佇列167
6.3.1什麼是阻塞佇列167
6.3.2Java里的阻塞佇列168
6.3.3阻塞佇列的實現原理172
6.4Fork/Join框架175
6.4.1什麼是Fork/Join框架175
6.4.2工作竊取算法176
6.4.3Fork/Join框架的設計177
6.4.4使用Fork/Join框架177
6.4.5Fork/Join框架的異常處理179
6.4.6Fork/Join框架的實現原理179
6.5本章小結181
第7章Java中的13個原子操作類182
7.1原子更新基本類型類182
7.2原子更新數組184
7.3原子更新引用類型185
7.4原子更新欄位類187
7.5本章小結188
第8章Java中的並發工具類189
8.1等待多執行緒完成的CountDownLatch189
8.2同步屏障CyclicBarrier191
8.2.1CyclicBarrier簡介191
8.2.2CyclicBarrier的套用場景193
8.2.3CyclicBarrier和CountDownLatch的區別195
8.3控制並發執行緒數的Semaphore196
8.4執行緒間交換數據的Exchanger198
8.5本章小結199
第9章Java中的執行緒池200
9.1執行緒池的實現原理200
9.2執行緒池的使用203
9.2.1執行緒池的創建203
9.2.2向執行緒池提交任務205
9.2.3關閉執行緒池205
9.2.4合理地配置執行緒池206
9.2.5執行緒池的監控206
9.3本章小結207
第10章Executor框架208
10.1Executor框架簡介208
10.1.1Executor框架的兩級調度模型208
10.1.2Executor框架的結構與成員208
10.2ThreadPoolExecutor詳解213
10.2.1FixedThreadPool詳解213
10.2.2SingleThreadExecutor詳解214
10.2.3CachedThreadPool詳解215
10.3ScheduledThreadPoolExecutor詳解217
10.3.1ScheduledThreadPoolExecutor的運行機制217
10.3.2ScheduledThreadPoolExecutor的實現218
10.4FutureTask詳解221
10.4.1FutureTask簡介222
10.4.2FutureTask的使用222
10.4.3FutureTask的實現224
10.5本章小結227
第11章Java並發編程實踐228
11.1生產者和消費者模式228
11.1.1生產者消費者模式實戰229
11.1.2多生產者和多消費者場景231
11.1.3執行緒池與生產消費者模式234
11.2線上問題定位234
11.3性能測試236
11.4異步任務池238
11.5本章小結240
文摘
假設一個執行緒A執行writer()方法,另一個執行緒B執行reader()方法。這裡的操作2使得對象還未完成構造前就為執行緒B可見。即使這裡的操作2是構造函式的最後一步,且在程式中操作2排在操作1後面,執行read()方法的執行緒仍然可能無法看到final域被初始化後的值,因為這裡的操作1和操作2之間可能被重排序。實際的執行時序可能如圖3—32所示。
從圖3—32可以看出:在構造函式返回前,被構造對象的引用不能為其他執行緒所見,因為此時的final域可能還沒有被初始化。在構造函式返回後,任意執行緒都將保證能看到final域正確初始化之後的值。
3.6.6 final語義在處理器中的實現
現在我們以X86處理器為例,說明final語義在處理器中的具體實現。
上面我們提到,寫final域的重排序規則會要求編譯器在final域的寫之後,構造函式return之前插入一個StoreStore障屏。讀final域的重排序規則要求編譯器在讀final域的操作前面插入一個LoadLoad屏障。
由於X86處理器不會對寫一寫操作做重排序,所以在X86處理器中,寫final域需要的StoreStore障屏會被省略掉。同樣,由於X86處理器不會對存在間接依賴關係的操作做重排序,所以在X86處理器中,讀final域需要的LoadLoad屏障也會被省略掉。也就是說,在X86處理器中,final域的讀/寫不會插入任何記憶體屏障!