并發(fā)編程領(lǐng)域的扛鼎之作,作者是阿里和1號(hào)店的資深Java技術(shù)專家,對(duì)并發(fā)編程有非常深入的研究,《Java并發(fā)編程的藝術(shù)》是他們多年一線開(kāi)發(fā)經(jīng)驗(yàn)的結(jié)晶。本書(shū)的部分內(nèi)容在出版早期發(fā)表在Java并發(fā)編程網(wǎng)和InfoQ等技術(shù)社區(qū),得到了非常高的評(píng)價(jià)。它選取了Java并發(fā)編程中最核心的技術(shù)進(jìn)行講解,從JDK源碼、JVM、CPU等多角度全面剖析和講解了Java并發(fā)編程的框架、工具、原理和方法,對(duì)Java并發(fā)編程進(jìn)行了最為深入和透徹的闡述。
《Java并發(fā)編程的藝術(shù)》內(nèi)容涵蓋Java并發(fā)編程機(jī)制的底層實(shí)現(xiàn)原理、Java內(nèi)存模型、Java并發(fā)編程基礎(chǔ)、Java中的鎖、并發(fā)容器和框架、原子類、并發(fā)工具類、線程池、Executor框架等主題,每個(gè)主題都做了深入的講解,同時(shí)通過(guò)實(shí)例介紹了如何應(yīng)用這些技術(shù)。
阿里系和1號(hào)店資深技術(shù)專家撰寫,Java并發(fā)編程領(lǐng)域的扛鼎之作,內(nèi)容在InfoQ等社群得到高度認(rèn)可
從JDK源碼、JVM、CPU等多角度全面剖析和講解Java并發(fā)編程的框架、原理和核心技術(shù)
隨著大數(shù)據(jù)時(shí)代的來(lái)臨,程序員可能每天要處理幾十個(gè)TB的數(shù)據(jù),如何讓程序快速且安全地處理各種大數(shù)據(jù),就需要掌握不同的并發(fā)編程模型和并發(fā)編程技巧。用戶的一個(gè)點(diǎn)擊,需要在毫秒級(jí)處理完多個(gè)任務(wù),同樣需要并發(fā)編程的參與。
并發(fā)編程是Java語(yǔ)言的重要特性之一,在Java平臺(tái)上提供了許多基本的并發(fā)功能來(lái)輔助開(kāi)發(fā)多線程應(yīng)用程序。然而,這些相對(duì)底層的并發(fā)功能與上層應(yīng)用程序的并發(fā)語(yǔ)義之間并不存在一種簡(jiǎn)單而直觀的映射關(guān)系。因此,如何在Java并發(fā)應(yīng)用程序中正確且高效地使用這些功能就成了Java開(kāi)發(fā)人員的關(guān)注重點(diǎn)。
《Java并發(fā)編程的藝術(shù)》正是為了解決這個(gè)問(wèn)題而寫的。書(shū)中采用循序漸進(jìn)的講解方式,從并發(fā)編程的底層實(shí)現(xiàn)機(jī)制入手,逐步介紹了在設(shè)計(jì)Java并發(fā)程序時(shí)各種重要的技術(shù)、設(shè)計(jì)模式與應(yīng)用,同時(shí)輔以豐富的示例代碼,使得開(kāi)發(fā)人員能夠更快地領(lǐng)悟Java并發(fā)編程的要領(lǐng),圍繞著Java平臺(tái)的基礎(chǔ)并發(fā)功能快速地構(gòu)建大規(guī)模的并發(fā)應(yīng)用程序。
為什么要寫這本書(shū)記得第一次寫并發(fā)編程的文章時(shí)還是在2012年,當(dāng)時(shí)花了幾個(gè)星期的時(shí)間寫了一篇文章《深入分析volatile的實(shí)現(xiàn)原理》,準(zhǔn)備在自己的博客中發(fā)表。在同事建法的建議下,懷著試一試的心態(tài)投向了InfoQ,慶幸的是半小時(shí)后得到InfoQ主編采納的回復(fù),高興之情無(wú)以言表。這也是我第一次在專業(yè)媒體上發(fā)表文章,而后在InfoQ編輯張龍的不斷鼓勵(lì)和支持下,我陸續(xù)在InfoQ發(fā)表了幾篇與并發(fā)編程相關(guān)的文章,于是便形成了“聊聊并發(fā)”專欄。在這個(gè)專欄的寫作過(guò)程中,我得到快速的成長(zhǎng)和非常多的幫助,在此非常感謝InfoQ的編輯們。2013年,華章的福川兄找到我,問(wèn)有沒(méi)有興趣寫一本書(shū),當(dāng)時(shí)覺(jué)得自己資歷尚淺,婉言拒絕了。后來(lái)和福川兄一直保持聯(lián)系,最后允許我花兩年的時(shí)間來(lái)完成本書(shū),所以答應(yīng)了下來(lái)。由于并發(fā)編程領(lǐng)域的技術(shù)點(diǎn)非常多且深,所以陸續(xù)又邀請(qǐng)了同事魏鵬和朋友曉明一起參與到本書(shū)的編寫當(dāng)中。
寫本書(shū)的過(guò)程也是對(duì)自己研究和掌握的技術(shù)點(diǎn)進(jìn)行整理的過(guò)程,希望本書(shū)能幫助讀者快速掌握并發(fā)編程技術(shù)。
本書(shū)一共11章,由三名作者共同編寫完成,其中第3章和第10章節(jié)由程曉明編寫,第4章和第5章由魏鵬編寫,其他7章由方騰飛編寫。
本書(shū)特色本書(shū)結(jié)合JDK的源碼介紹了Java并發(fā)框架、線程池的實(shí)現(xiàn)原理,幫助讀者做到知其所以然。
本書(shū)對(duì)原理的剖析不僅僅局限于Java層面,而是深入到JVM,甚至CPU層面來(lái)進(jìn)行講解,幫助讀者從更底層看并發(fā)技術(shù)。
本書(shū)結(jié)合線上應(yīng)用,給出了一些并發(fā)編程實(shí)戰(zhàn)技巧,以及線上處理并發(fā)問(wèn)題的步驟和思路。
方騰飛(花名清英,英文名kiral),
螞蟻金服集團(tuán)技術(shù)專家,從事Java開(kāi)發(fā)近10年。5年以上的團(tuán)隊(duì)管理、項(xiàng)目管理和敏捷開(kāi)發(fā)經(jīng)驗(yàn),崇尚團(tuán)隊(duì)合作。曾參與CMS、電子海圖、SOC、ITIL、電子商務(wù)網(wǎng)站和信貸管理系統(tǒng)等項(xiàng)目。目前在螞蟻金服網(wǎng)商銀行貸款管理團(tuán)隊(duì)負(fù)責(zé)數(shù)據(jù)采集平臺(tái)開(kāi)發(fā)工作。與同事合作開(kāi)發(fā)了tala code Review插件,深受阿里數(shù)千名工程師擁躉,并開(kāi)發(fā)過(guò)開(kāi)源工具jdbcutil(https://github.com/kiral/utils)。創(chuàng)辦了并發(fā)編程網(wǎng),組織翻譯了百余篇國(guó)外優(yōu)秀技術(shù)文章,并曾為InfoQ撰寫“聊聊并發(fā)”專欄,在《程序員》雜志撰寫敏捷實(shí)踐系列文章
魏 鵬,
阿里巴巴集團(tuán)技術(shù)專家,在阿里巴巴中國(guó)網(wǎng)站技術(shù)部工作多年,曾擔(dān)任中國(guó)網(wǎng)站交易平臺(tái)架構(gòu)師,主導(dǎo)了交易系統(tǒng)服務(wù)化工作,設(shè)計(jì)實(shí)現(xiàn)的數(shù)據(jù)遷移系統(tǒng)高效地完成了阿里巴巴中國(guó)網(wǎng)站交易數(shù)據(jù)到阿里巴巴集團(tuán)的遷移工作。目前在阿里巴巴共享業(yè)務(wù)事業(yè)部從事Java應(yīng)用容器Pandora和服務(wù)框架HSF的相關(guān)工作,其中Java應(yīng)用容器Pandora是阿里巴巴中間件運(yùn)行的基礎(chǔ),而服務(wù)框架HSF則是阿里巴巴集團(tuán)實(shí)現(xiàn)服務(wù)化的主要解決方案,二者在阿里巴巴擁有最為廣泛的使用量。個(gè)人平時(shí)喜歡閱讀技術(shù)書(shū)籍,翻譯一些國(guó)外優(yōu)秀文檔,喜歡總結(jié)、樂(lè)于分享,對(duì)Java應(yīng)用容器、多線程編程以及分布式系統(tǒng)感興趣。
程曉明,
1號(hào)店資深架構(gòu)師,從事1號(hào)店交易平臺(tái)系統(tǒng)的開(kāi)發(fā),技術(shù)上關(guān)注并發(fā)與NIO。因5年前遇到的一個(gè)線上故障,解決過(guò)程中對(duì)Java并發(fā)編程產(chǎn)生了濃厚的興趣,從此開(kāi)始了漫長(zhǎng)的探索之旅:從底層實(shí)現(xiàn)機(jī)制、內(nèi)存模型到Java同步?v觀我自己對(duì)Java并發(fā)的學(xué)習(xí)過(guò)程,是一個(gè)從高層到底層再到高層的一個(gè)反復(fù)迭代的過(guò)程,我估計(jì)很多讀者的學(xué)習(xí)過(guò)程應(yīng)該與我類似。文章多見(jiàn)諸《IBM developerWorks》、InfoQ和《程序員》雜志。
前 言
第1章 并發(fā)編程的挑戰(zhàn) 1
1.1 上下文切換 1
1.1.1 多線程一定快嗎 1
1.1.2 測(cè)試上下文切換次數(shù)和時(shí)長(zhǎng) 3
1.1.3 如何減少上下文切換 3
1.1.4 減少上下文切換實(shí)戰(zhàn) 4
1.2 死鎖 5
1.3 資源限制的挑戰(zhàn) 6
1.4 本章小結(jié) 7
第2章 Java并發(fā)機(jī)制的底層實(shí)現(xiàn)原理 8
2.1 volatile的應(yīng)用 8
2.2 synchronized的實(shí)現(xiàn)原理與應(yīng)用 11
2.2.1 Java對(duì)象頭 12
2.2.2 鎖的升級(jí)與對(duì)比 13
2.3 原子操作的實(shí)現(xiàn)原理 16
2.4 本章小結(jié) 20
第3章 Java內(nèi)存模型 21
3.1 Java內(nèi)存模型的基礎(chǔ) 21
3.1.1 并發(fā)編程模型的兩個(gè)關(guān)鍵問(wèn)題 21
3.1.2 Java內(nèi)存模型的抽象結(jié)構(gòu) 22
3.1.3 從源代碼到指令序列的重排序 23
3.1.4 并發(fā)編程模型的分類 24
3.1.5 happens-before簡(jiǎn)介 26
3.2 重排序 27
3.2.1 數(shù)據(jù)依賴性 28
3.2.2 as-if-serial語(yǔ)義 28
3.2.3 程序順序規(guī)則 29
3.2.4 重排序?qū)Χ嗑程的影響 29
3.3 順序一致性 31
3.3.1 數(shù)據(jù)競(jìng)爭(zhēng)與順序一致性 31
3.3.2 順序一致性內(nèi)存模型 32
3.3.3 同步程序的順序一致性效果 34
3.3.4 未同步程序的執(zhí)行特性 35
3.4 volatile的內(nèi)存語(yǔ)義 38
3.4.1 volatile的特性 38
3.4.2 volatile寫-讀建立的happens-before關(guān)系 39
3.4.3 volatile寫-讀的內(nèi)存語(yǔ)義 40
3.4.4 volatile內(nèi)存語(yǔ)義的實(shí)現(xiàn) 42
3.4.5 JSR-133為什么要增強(qiáng)volatile的內(nèi)存語(yǔ)義 46
3.5 鎖的內(nèi)存語(yǔ)義 47
3.5.1 鎖的釋放-獲取建立的
happens-before關(guān)系 47
3.5.2 鎖的釋放和獲取的內(nèi)存語(yǔ)義 48
3.5.3 鎖內(nèi)存語(yǔ)義的實(shí)現(xiàn) 50
3.5.4 concurrent包的實(shí)現(xiàn) 54
3.6 final域的內(nèi)存語(yǔ)義 55
3.6.1 final域的重排序規(guī)則 55
3.6.2 寫final域的重排序規(guī)則 56
3.6.3 讀final域的重排序規(guī)則 57
3.6.4 final域?yàn)橐妙愋?58
3.6.5 為什么final引用不能從構(gòu)造函數(shù)內(nèi)“溢出” 59
3.6.6 final語(yǔ)義在處理器中的實(shí)現(xiàn) 61
3.6.7 JSR-133為什么要增強(qiáng)f?inal的語(yǔ)義 62
3.7 happens-before 62
3.7.1 JMM的設(shè)計(jì) 62
3.7.2 happens-before的定義 64
3.7.3 happens-before規(guī)則 65
3.8 雙重檢查鎖定與延遲初始化 67
3.8.1 雙重檢查鎖定的由來(lái) 67
3.8.2 問(wèn)題的根源 69
3.8.3 基于volatile的解決方案 71
3.8.4 基于類初始化的解決方案 72
3.9 Java內(nèi)存模型綜述 78
3.9.1 處理器的內(nèi)存模型 78
3.9.2 各種內(nèi)存模型之間的關(guān)系 80
3.9.3 JMM的內(nèi)存可見(jiàn)性保證 80
3.9.4 JSR-133對(duì)舊內(nèi)存模型的修補(bǔ) 81
3.10 本章小結(jié) 82
第4章 Java并發(fā)編程基礎(chǔ) 83
4.1 線程簡(jiǎn)介 83
4.1.1 什么是線程 83
4.1.2 為什么要使用多線程 84
4.1.3 線程優(yōu)先級(jí) 85
4.1.4 線程的狀態(tài) 87
4.1.5 Daemon線程 90
4.2 啟動(dòng)和終止線程 91
4.2.1 構(gòu)造線程 91
4.2.2 啟動(dòng)線程 92
4.2.3 理解中斷 92
4.2.4 過(guò)期的suspend()、resume()和stop() 93
4.2.5 安全地終止線程 95
4.3 線程間通信 96
4.3.1 volatile和synchronized關(guān)鍵字 96
4.3.2 等待/通知機(jī)制 98
4.3.3 等待/通知的經(jīng)典范式 101
4.3.4 管道輸入/輸出流 102
4.3.5 Thread.join()的使用 103
4.3.6 ThreadLocal的使用 105
4.4 線程應(yīng)用實(shí)例 106
4.4.1 等待超時(shí)模式 106
4.4.2 一個(gè)簡(jiǎn)單的數(shù)據(jù)庫(kù)連接池示例 106
4.4.3 線程池技術(shù)及其示例 110
4.4.4 一個(gè)基于線程池技術(shù)的簡(jiǎn)單Web服務(wù)器 114
4.5 本章小結(jié) 118
第5章 Java中的鎖 119
5.1 Lock接口 119
5.2 隊(duì)列同步器 121
5.2.1 隊(duì)列同步器的接口與示例 121
5.2.2 隊(duì)列同步器的實(shí)現(xiàn)分析 124
5.3 重入鎖 136
5.4 讀寫鎖 140
5.4.1 讀寫鎖的接口與示例 141
5.4.2 讀寫鎖的實(shí)現(xiàn)分析 142
5.5 LockSupport工具 146
5.6 Condition接口 147
5.6.1 Condition接口與示例 148
5.6.2 Condition的實(shí)現(xiàn)分析 150
5.7 本章小結(jié) 154
第6章 Java并發(fā)容器和框架 155
6.1 ConcurrentHashMap的實(shí)現(xiàn)原理與使用 155
6.1.1 為什么要使用ConcurrentHashMap 155
6.1.2 ConcurrentHashMap的結(jié)構(gòu) 156
6.1.3 ConcurrentHashMap的初始化 157
6.1.4 定位Segment 159
6.1.5 ConcurrentHashMap的操作 160
6.2 ConcurrentLinkedQueue 161
6.2.1 ConcurrentLinkedQueue的結(jié)構(gòu) 162
6.2.2 入隊(duì)列 162
6.2.3 出隊(duì)列 165
6.3 Java中的阻塞隊(duì)列 167
6.3.1 什么是阻塞隊(duì)列 167
6.3.2 Java里的阻塞隊(duì)列 168
6.3.3 阻塞隊(duì)列的實(shí)現(xiàn)原理 172
6.4 Fork/Join框架 175
6.4.1 什么是Fork/Join框架 175
6.4.2 工作竊取算法 176
6.4.3 Fork/Join框架的設(shè)計(jì) 177
6.4.4 使用Fork/Join框架 177
6.4.5 Fork/Join框架的異常處理 179
6.4.6 Fork/Join框架的實(shí)現(xiàn)原理 179
6.5 本章小結(jié) 181
第7章 Java中的13個(gè)原子操作類 182
7.1 原子更新基本類型類 182
7.2 原子更新數(shù)組 184
7.3 原子更新引用類型 185
7.4 原子更新字段類 187
7.5 本章小結(jié) 188
第8章 Java中的并發(fā)工具類 189
8.1 等待多線程完成的CountDownLatch 189
8.2 同步屏障CyclicBarrier 191
8.2.1 CyclicBarrier簡(jiǎn)介 191
8.2.2 CyclicBarrier的應(yīng)用場(chǎng)景 193
8.2.3 CyclicBarrier和CountDownLatch的區(qū)別 195
8.3 控制并發(fā)線程數(shù)的Semaphore 196
8.4 線程間交換數(shù)據(jù)的Exchanger 198
8.5 本章小結(jié) 199
第9章 Java中的線程池 200
9.1 線程池的實(shí)現(xiàn)原理 200
9.2 線程池的使用 203
9.2.1 線程池的創(chuàng)建 203
9.2.2 向線程池提交任務(wù) 205
9.2.3 關(guān)閉線程池 205
9.2.4 合理地配置線程池 206
9.2.5 線程池的監(jiān)控 206
9.3 本章小結(jié) 207
第10章 Executor框架 208
10.1 Executor框架簡(jiǎn)介 208
10.1.1 Executor框架的兩級(jí)調(diào)度模型 208
10.1.2 Executor框架的結(jié)構(gòu)與成員 208
10.2 ThreadPoolExecutor詳解 213
10.2.1 FixedThreadPool詳解 213
10.2.2 SingleThreadExecutor詳解 214
10.2.3 CachedThreadPool詳解 215
10.3 ScheduledThreadPoolExecutor詳解 217
10.3.1 ScheduledThreadPoolExecutor的運(yùn)行機(jī)制 217
10.3.2 ScheduledThreadPoolExecutor的實(shí)現(xiàn) 218
10.4 FutureTask詳解 221
10.4.1 FutureTask簡(jiǎn)介 222
10.4.2 FutureTask的使用 222
10.4.3 FutureTask的實(shí)現(xiàn) 224
10.5 本章小結(jié) 227
第11章 Java并發(fā)編程實(shí)踐 228
11.1 生產(chǎn)者和消費(fèi)者模式 228
11.1.1 生產(chǎn)者消費(fèi)者模式實(shí)戰(zhàn) 229
11.1.2 多生產(chǎn)者和多消費(fèi)者場(chǎng)景 231
11.1.3 線程池與生產(chǎn)消費(fèi)者模式 234
11.2 線上問(wèn)題定位 234
11.3 性能測(cè)試 236
11.4 異步任務(wù)池 238
11.5 本章小結(jié) 240