出版時間:2012-2 出版社:機械工業(yè)出版社華章公司 作者:Brian Goetz,Tim Peierls,Joshua Bloch,Joseph Bowbeer,David Holmes,Doug Lea 頁數(shù):312 譯者:童云蘭
Tag標(biāo)簽:無
前言
前言 在寫作本書時,對于中端桌面系統(tǒng)來說,多核處理器正變得越來越便宜。無獨有偶,許多開發(fā)團隊也注意到,在他們的項目中出現(xiàn)了越來越多與線程有關(guān)的錯誤報告。在NetBeans開發(fā)者網(wǎng)站上的最近一次公告中,一位核心維護人員注意到,為了修復(fù)與線程相關(guān)的問題,在某個類中竟然打了14次補丁。Dion Almaer,這位TheServerSide網(wǎng)站的前編輯,最近(在經(jīng)過一番痛苦的調(diào)試過程并最終發(fā)現(xiàn)了一個與線程有關(guān)的錯誤之后)在其博客上寫道,在大多數(shù)Java程序中充滿了各種并發(fā)錯誤,使得程序只有在“偶然的情況下”才能正常工作?! 〈_實,在開發(fā)、測試以及調(diào)試多線程程序時存在著巨大的困難,因為并發(fā)性錯誤通常并不會以某種確定的方式顯現(xiàn)出來。當(dāng)這些錯誤出現(xiàn)時,通常是在最糟糕的時刻,例如在正式產(chǎn)品中,或者在高負載的情況下?! ‘?dāng)開發(fā)Java并發(fā)程序時,所要面對的挑戰(zhàn)之一就是:平臺提供的各種并發(fā)功能與開發(fā)人員在程序中需要的并發(fā)語義并不匹配。在Java語言中提供了一些底層機制,例如同步和條件等待,但在使用這些機制來實現(xiàn)應(yīng)用級的協(xié)議與策略時必須始終保持一致。如果沒有這些策略,那么在編寫程序時,雖然程序看似能順利地編譯和運行,但卻總會出現(xiàn)各種奇怪的問題。許多介紹并發(fā)的其他書籍更側(cè)重于介紹一些底層機制和API,而在設(shè)計級的策略和模式上敘述的不多?! ava 5.0在Java并發(fā)應(yīng)用程序的開發(fā)方面進展巨大,它不僅提供了一些新的高層組件,還補充了一些底層機制,從而使得無論是新手級開發(fā)人員還是專家級開發(fā)人員都能夠更容易地構(gòu)建并發(fā)應(yīng)用程序。本書的作者都是JCP專家組的主要成員,也正是該專家組編寫了這些新功能。本書不僅描述了這些新功能的行為和特性,還介紹了它們的底層設(shè)計模式和促使它們被添加到平臺庫中的應(yīng)用場景。 我們的目標(biāo)是向讀者介紹一些設(shè)計規(guī)則和思維模式,從而使讀者能夠更容易也更樂意去構(gòu)建正確的以及高性能的Java并發(fā)類和應(yīng)用程序?! ∥覀兿M隳芟硎鼙緯拈喿x過程?! rian Goetz Williston,VT 2006年3月
內(nèi)容概要
本書深入淺出地介紹了Java線程和并發(fā),是一本完美的Java并發(fā)參考手冊。書中從并發(fā)性和線程安全性的基本概念出發(fā),介紹了如何使用類庫提供的基本并發(fā)構(gòu)建塊,用于避免并發(fā)危險、構(gòu)造線程安全的類及驗證線程安全的規(guī)則,如何將小的線程安全類組合成更大的線程安全類,如何利用線程來提高并發(fā)應(yīng)用程序的吞吐量,如何識別可并行執(zhí)行的任務(wù),如何提高單線程子系統(tǒng)的響應(yīng)性,如何確保并發(fā)程序執(zhí)行預(yù)期任務(wù),如何提高并發(fā)代碼的性能和可伸縮性等內(nèi)容,最后介紹了一些高級主題,如顯式鎖、原子變量、非阻塞算法以及如何開發(fā)自定義的同步工具類。
本書適合Java程序開發(fā)人員閱讀。
作者簡介
本書作者都是Java Community Process JSR
166專家組(并發(fā)工具)的主要成員,并在其他很多JCP專家組里任職。Brian
Goetz有20多年的軟件咨詢行業(yè)經(jīng)驗,并著有至少75篇關(guān)于Java開發(fā)的文章。Tim
Peierls是“現(xiàn)代多處理器”的典范,他在BoxPop.biz、唱片藝術(shù)和戲劇表演方面也頗有研究。Joseph
Bowbeer是一個Java ME專家,他對并發(fā)編程的興趣始于Apollo計算機時代。David Holmes是《The Java
Programming Language》一書的合著者,任職于Sun公司。Joshua
Bloch是Google公司的首席Java架構(gòu)師,《Effective Java》一書的作者,并參與著作了《Java
Puzzlers》。Doug Lea是《Concurrent Programming》一書的作者,紐約州立大學(xué)
Oswego分校的計算機科學(xué)教授。
書籍目錄
對本書的贊譽
譯者序
前 言
第1章 簡介
1.1 并發(fā)簡史
1.2 線程的優(yōu)勢
1.2.1 發(fā)揮多處理器的強大能力
1.2.2 建模的簡單性
1.2.3 異步事件的簡化處理
1.2.4 響應(yīng)更靈敏的用戶界面
1.3 線程帶來的風(fēng)險
1.3.1 安全性問題
1.3.2 活躍性問題
1.3.3 性能問題
1.4 線程無處不在
第一部分 基礎(chǔ)知識
第2章 線程安全性
2.1 什么是線程安全性
2.2 原子性
2.2.1 競態(tài)條件
2.2.2 示例:延遲初始化中的競態(tài)條件
2.2.3 復(fù)合操作
2.3 加鎖機制
2.3.1 內(nèi)置鎖
2.3.2 重入
2.4 用鎖來保護狀態(tài)
2.5 活躍性與性能
第3章 對象的共享
3.1 可見性
3.1.1 失效數(shù)據(jù)
3.1.2 非原子的64位操作
3.1.3 加鎖與可見性
3.1.4 Volatile變量
3.2 發(fā)布與逸出
3.3 線程封閉
3.3.1 Ad-hoc線程封閉
3.3.2 棧封閉
3.3.3 ThreadLocal類
3.4 不變性
3.4.1 Final域
3.4.2 示例:使用Volatile類型來發(fā)布不可變對象
3.5 安全發(fā)布
3.5.1 不正確的發(fā)布:正確的對象被破壞
3.5.2 不可變對象與初始化安全性
3.5.3 安全發(fā)布的常用模式
3.5.4 事實不可變對象
3.5.5 可變對象
3.5.6 安全地共享對象
第4章 對象的組合
4.1 設(shè)計線程安全的類
4.1.1 收集同步需求
4.1.2 依賴狀態(tài)的操作
4.1.3 狀態(tài)的所有權(quán)
4.2 實例封閉
4.2.1 Java監(jiān)視器模式
4.2.2 示例:車輛追蹤
4.3 線程安全性的委托
4.3.1 示例:基于委托的車輛追蹤器
4.3.2 獨立的狀態(tài)變量
4.3.3 當(dāng)委托失效時
4.3.4 發(fā)布底層的狀態(tài)變量
4.3.5 示例:發(fā)布狀態(tài)的車輛追蹤器
4.4 在現(xiàn)有的線程安全類中添加功能
4.4.1 客戶端加鎖機制
4.4.2 組合
4.5 將同步策略文檔化
第5章 基礎(chǔ)構(gòu)建模塊
5.1 同步容器類
5.1.1 同步容器類的問題
5.1.2 迭代器與Concurrent-ModificationException
5.1.3 隱藏迭代器
5.2 并發(fā)容器
5.2.1 ConcurrentHashMap
5.2.2 額外的原子Map操作
5.2.3 CopyOnWriteArrayList
5.3 阻塞隊列和生產(chǎn)者-消費者模式
5.3.1 示例:桌面搜索
5.3.2 串行線程封閉
5.3.3 雙端隊列與工作密取
5.4 阻塞方法與中斷方法
5.5 同步工具類
5.5.1 閉鎖
5.5.2 FutureTask
5.5.3 信號量
5.5.4 柵欄
5.6 構(gòu)建高效且可伸縮的結(jié)果緩存
第二部分 結(jié)構(gòu)化并發(fā)應(yīng)用程序
第6章 任務(wù)執(zhí)行
6.1 在線程中執(zhí)行任務(wù)
6.1.1 串行地執(zhí)行任務(wù)
6.1.2 顯式地為任務(wù)創(chuàng)建線程
6.1.3 無限制創(chuàng)建線程的不足
6.2 Executor框架
6.2.1 示例:基于Executor的Web服務(wù)器
6.2.2 執(zhí)行策略
6.2.3 線程池
6.2.4 Executor的生命周期
6.2.5 延遲任務(wù)與周期任務(wù)
6.3 找出可利用的并行性
6.3.1 示例:串行的頁面渲染器
6.3.2 攜帶結(jié)果的任務(wù)Callable與Future
6.3.3 示例:使用Future實現(xiàn)頁面渲染器
6.3.4 在異構(gòu)任務(wù)并行化中存在的局限
6.3.5 CompletionService:Executor與BlockingQueue
6.3.6 示例:使用CompletionService實現(xiàn)頁面渲染器
6.3.7 為任務(wù)設(shè)置時限
6.3.8 示例:旅行預(yù)定門戶網(wǎng)站
第7章 取消與關(guān)閉
7.1 任務(wù)取消
7.1.1 中斷
7.1.2 中斷策略
7.1.3 響應(yīng)中斷
7.1.4 示例:計時運行
7.1.5 通過Future來實現(xiàn)取消
7.1.6 處理不可中斷的阻塞
7.1.7 采用newTaskFor來封裝非標(biāo)準(zhǔn)的取消
7.2 停止基于線程的服務(wù)
7.2.1 示例:日志服務(wù)
7.2.2 關(guān)閉ExecutorService
7.2.3 “毒丸”對象
7.2.4 示例:只執(zhí)行一次的服務(wù)
7.2.5 shutdownNow的局限性
7.3 處理非正常的線程終止
7.4 JVM關(guān)閉
7.4.1 關(guān)閉鉤子
7.4.2 守護線程
7.4.3 終結(jié)器
第8章 線程池的使用
8.1 在任務(wù)與執(zhí)行策略之間的隱性耦合
8.1.1 線程饑餓死鎖
8.1.2 運行時間較長的任務(wù)
8.2 設(shè)置線程池的大小
8.3 配置ThreadPoolExecutor
8.3.1 線程的創(chuàng)建與銷毀
8.3.2 管理隊列任務(wù)
8.3.3 飽和策略
8.3.4 線程工廠
8.3.5 在調(diào)用構(gòu)造函數(shù)后再定制ThreadPoolExecutor
8.4 擴展 ThreadPoolExecutor
8.5 遞歸算法的并行化
第9章 圖形用戶界面應(yīng)用程序
9.1 為什么GUI是單線程的
9.1.1 串行事件處理
9.1.2 Swing中的線程封閉機制
9.2 短時間的GUI任務(wù)
9.3 長時間的GUI任務(wù)
9.3.1 取消
9.3.2 進度標(biāo)識和完成標(biāo)識
9.3.3 SwingWorker
9.4 共享數(shù)據(jù)模型
9.4.1 線程安全的數(shù)據(jù)模型
9.4.2 分解數(shù)據(jù)模型
9.5 其他形式的單線程子系統(tǒng)
第三部分 活躍性、性能與測試
第10章 避免活躍性危險
10.1 死鎖
10.1.1 鎖順序死鎖
10.1.2 動態(tài)的鎖順序死鎖
10.1.3 在協(xié)作對象之間發(fā)生的死鎖
10.1.4 開放調(diào)用
10.1.5 資源死鎖
10.2 死鎖的避免與診斷
10.2.1 支持定時的鎖
10.2.2 通過線程轉(zhuǎn)儲信息來分析死鎖
10.3 其他活躍性危險
10.3.1 饑餓
10.3.2 糟糕的響應(yīng)性
10.3.3 活鎖
第11章 性能與可伸縮性
11.1 對性能的思考
11.1.1 性能與可伸縮性
11.1.2 評估各種性能權(quán)衡因素
11.2 Amdahl定律
11.2.1 示例:在各種框架中隱藏的串行部分
11.2.2 Amdahl定律的應(yīng)用
11.3 線程引入的開銷
11.3.1 上下文切換
11.3.2 內(nèi)存同步
11.3.3 阻塞
11.4 減少鎖的競爭
11.4.1 縮小鎖的范圍(“快進快出”)
11.4.2 減小鎖的粒度
11.4.3 鎖分段
11.4.4 避免熱點域
11.4.5 一些替代獨占鎖的方法
11.4.6 監(jiān)測CPU的利用率
11.4.7 向?qū)ο蟪卣f“不”
11.5 示例:比較Map的性能
11.6 減少上下文切換的開銷
第12章 并發(fā)程序的測試
12.1 正確性測試
12.1.1 基本的單元測試
12.1.2 對阻塞操作的測試
12.1.3 安全性測試
12.1.4 資源管理的測試
12.1.5 使用回調(diào)
12.1.6 產(chǎn)生更多的交替操作
12.2 性能測試
12.2.1 在PutTakeTest中增加計時功能
12.2.2 多種算法的比較
12.2.3 響應(yīng)性衡量
12.3 避免性能測試的陷阱
12.3.1 垃圾回收
12.3.2 動態(tài)編譯
12.3.3 對代碼路徑的不真實采樣
12.3.4 不真實的競爭程度
12.3.5 無用代碼的消除
12.4 其他的測試方法
12.4.1 代碼審查
12.4.2 靜態(tài)分析工具
12.4.3 面向方面的測試技術(shù)
12.4.4 分析與監(jiān)測工具
第四部分 高級主題
第13章 顯式鎖
13.1 Lock與 ReentrantLock
13.1.1 輪詢鎖與定時鎖
13.1.2 可中斷的鎖獲取操作
13.1.3 非塊結(jié)構(gòu)的加鎖
13.2 性能考慮因素
13.3 公平性
13.4 在synchronized和ReentrantLock之間進行選擇
13.5 讀-寫鎖
第14章 構(gòu)建自定義的同步工具
14.1 狀態(tài)依賴性的管理
14.1.1 示例:將前提條件的失敗傳遞給調(diào)用者
14.1.2 示例:通過輪詢與休眠來實現(xiàn)簡單的阻塞
14.1.3 條件隊列
14.2 使用條件隊列
14.2.1 條件謂詞
14.2.2 過早喚醒
14.2.3 丟失的信號
14.2.4 通知
14.2.5 示例:閥門類
14.2.6 子類的安全問題
14.2.7 封裝條件隊列
14.2.8 入口協(xié)議與出口協(xié)議
14.3 顯式的Condition對象
14.4 Synchronizer剖析
14.5 AbstractQueuedSynchronizer
14.6 java.util.concurrent同步器類中的 AQS
14.6.1 ReentrantLock
14.6.2 Semaphore與CountDownLatch
14.6.3 FutureTask
14.6.4 ReentrantReadWriteLock
第15章 原子變量與非阻塞同步機制
15.1 鎖的劣勢
15.2 硬件對并發(fā)的支持
15.2.1 比較并交換
15.2.2 非阻塞的計數(shù)器
15.2.3 JVM對CAS的支持
15.3 原子變量類
15.3.1 原子變量是一種“更好的volatile”
15.3.2 性能比較:鎖與原子變量
15.4 非阻塞算法
15.4.1 非阻塞的棧
15.4.2 非阻塞的鏈表
15.4.3 原子的域更新器
15.4.4 ABA問題
第16章 Java內(nèi)存模型
16.1 什么是內(nèi)存模型,為什么需要它
16.1.1 平臺的內(nèi)存模型
16.1.2 重排序
16.1.3 Java內(nèi)存模型簡介
16.1.4 借助同步
16.2 發(fā)布
16.2.1 不安全的發(fā)布
16.2.2 安全的發(fā)布
16.2.3 安全初始化模式
16.2.4 雙重檢查加鎖
16.3 初始化過程中的安全性
附錄A 并發(fā)性標(biāo)注
參考文獻
章節(jié)摘錄
版權(quán)頁:插圖:第一章 簡介編寫正確的程序很難,而編寫正確的并發(fā)程序則難上加難。與串行程序相比,在并發(fā)程序中存在更多容易出錯的地方。那么,為什么還要編寫并發(fā)程序?線程是Java語言中不可或缺的重要功能,它們能使復(fù)雜的異步代碼變得更簡單,從而極大地簡化了復(fù)雜系統(tǒng)的開發(fā)。此外,要想充分發(fā)揮多處理器系統(tǒng)的強大計算能力,最簡單的方式就是使用線程。隨著處理器數(shù)量的持續(xù)增長,如何高效地使用并發(fā)正變得越來越重要。1.1 并發(fā)簡史在早期的計算機中不包含操作系統(tǒng),它們從頭到尾只執(zhí)行一個程序,并且這個程序能訪問計算機中的所有資源。在這種裸機環(huán)境中,不僅很難編寫和運行程序,而且每次只能運行一個程序,這對于昂貴并且稀有的計算機資源來說也是一種浪費。操作系統(tǒng)的出現(xiàn)使得計算機每次能運行多個程序,并且不同的程序都在單獨的進程中運行:操作系統(tǒng)為各個獨立執(zhí)行的進程分配各種資源,包括內(nèi)存,文件句柄以及安全證書等。如果需要的話,在不同的進程之間可以通過一些粗粒度的通信機制來交換數(shù)據(jù),包括:套接字、信號處理器、共享內(nèi)存、信號量以及文件等。之所以在計算機中加入操作系統(tǒng)來實現(xiàn)多個程序的同時執(zhí)行,主要是基于以下原因:資源利用率。在某些情況下,程序必須等待某個外部操作執(zhí)行完成,例如輸入操作或輸出操作等,而在等待時程序無法執(zhí)行其他任何工作。因此,如果在等待的同時可以運行另一個程序,那么無疑將提高資源的利用率。公平性。不同的用戶和翠序?qū)τ谟嬎銠C上的資源有著同等的使用權(quán)。一種高效的運行方式是通過粗粒度的時間分片(Time Slicing)使這些用戶和程序能共享計算機資源,而不是由一個程序從頭運行到尾,然后再啟動下一個程序。便利性。通常來說,在計算多個任務(wù)時,應(yīng)該編寫多個程序,每個程序執(zhí)行一個任務(wù)并在必要時相互通信,這比只編寫一個程序來計算所有任務(wù)更容易實現(xiàn)。
媒體關(guān)注與評論
“我曾有幸在一個偉大的團隊中工作,參與設(shè)計和實現(xiàn)在Java 5.0和Java 6等平臺中新增的并發(fā)功能?,F(xiàn)在,仍然是這個團隊,將透徹地講解這些新功能,以及關(guān)于并發(fā)的一般性概念。并發(fā)已不再只是高級用戶談?wù)摰脑掝},每一位Java開發(fā)人員都應(yīng)該閱讀這本書?!薄 狹artin Buchholz,Sun公司的JDK并發(fā)大師“在過去30多年時間里,計算機性能一直遵循著摩爾定律,但從現(xiàn)在開始,它將遵循Amdahl定律。編寫能高效利用多處理器的代碼非常具有挑戰(zhàn)性。在這本書中介紹的一些概念和技術(shù),對于在當(dāng)前(以及未來的)系統(tǒng)上編寫安全的和可伸縮的代碼來說都是非常有用的。” ——Doron Rajwan,Intel公司研究人員“如果你正在編寫、設(shè)計、調(diào)試、維護以及分析多線程的Java程序,那么本書正是你所需要的。如果你曾對某個方法進行過同步,但卻不理解其中的原因,那么你以及你的用戶都有必要從頭至尾仔細地讀一讀這本書?!薄 猅ed Neward,《Effective Enterprise Java》的作者“Brian非常清晰地闡述了并發(fā)的一些基本問題與復(fù)雜性。對于使用線程并關(guān)注程序執(zhí)行性能的開發(fā)人員來說,這是一本必讀的書。” ——Kirk Pepperdine,JavaPerformanceTuning網(wǎng)站CTO“本書深入淺出地介紹了一些復(fù)雜的編程主題,是一本完美的Java并發(fā)參考手冊。書中的每一頁都包含了程序員日常需要應(yīng)對的問題(以及相應(yīng)的解決方案)。隨著摩爾定律的發(fā)展趨勢由提高處理器核的速度轉(zhuǎn)向增加處理器核的數(shù)量,如何有效地利用并發(fā)性已變得越來越重要,本書正好介紹了這些方面的內(nèi)容?!薄 狢liff Click博士,Azul Systems公司高級軟件工程師“我對并發(fā)有著濃厚的興趣,并且與大多數(shù)程序員相比,我或許寫過更多存在線程死鎖的代碼,也在同步上犯了更多的錯誤。在介紹Java線程和并發(fā)等主題的眾多書籍中,Brian的這本書最具可讀性,它通過循序漸進的方式將一些復(fù)雜的主題闡述得很清楚。我將本書推薦給Java Specialists?Newsletter的所有讀者,因為它不僅有趣,而且很有用,它介紹了當(dāng)前Java開發(fā)人員正在面對的許多問題?!薄 狧einz Kabutz博士,Java Specialists'Newsletter的維護者“我一直努力想使一些簡單的問題變得更簡單,然而本書已經(jīng)簡化了一個復(fù)雜但卻關(guān)鍵的主題:并發(fā)。這本書采用了創(chuàng)新的講解方法、簡單明了的風(fēng)格,它注定會成為一本非常重要的書。 ——Bruce Tate,《Beyond Java》的作者這本書為Java開發(fā)人員在線程編程領(lǐng)域提供了不可多得的知識。我在讀這本書時受到了極大的啟發(fā),部分原因在于它詳細地介紹了Java中并發(fā)領(lǐng)域的API,但更重要的卻在于這本書以一種透徹并且易懂的方式來介紹復(fù)雜的并發(fā)知識,這是其他書籍很難媲美的。 ——Bill Venners,《Inside the Java Virtual Machine》的作者
編輯推薦
《Java并發(fā)編程實戰(zhàn)》第16屆Jolt大獎提名圖書,JavaOne大會最暢銷圖書,了解Java并發(fā)編程必讀佳作。線程是Java平臺的基礎(chǔ)組成部分之一。隨著多核處理器逐漸成為主流,如何高效地使用并發(fā)已成為構(gòu)建高性能應(yīng)用程序的重要因素。Java SE 5和Java 6在并發(fā)程序開發(fā)方面取得了巨大的進步,在其Java虛擬機中能支持一些高性能的并且具有高可伸縮性的并發(fā)類,此外還支持一組新的并發(fā)基礎(chǔ)構(gòu)建模塊。在《Java并發(fā)編程實戰(zhàn)》中,這些新功能的編寫者們不僅介紹了它們的工作原理和使用方式,還介紹了隱藏在這些功能背后的研究背景與設(shè)計模式。然而,在開發(fā)、測試以及調(diào)試多線程的程序時仍然存在巨大的困難。開發(fā)人員很容易編寫出一些看似能正常工作,但在一些情況下仍然會失敗的程序(包括在正式發(fā)布的產(chǎn)品中,以及在高負載環(huán)境中)?!禞ava并發(fā)編程實戰(zhàn)》不僅講解了并發(fā)的理論基礎(chǔ),還介紹了各種實際的開發(fā)技術(shù),這些知識對于構(gòu)建可靠的、可伸縮的以及可維護的并發(fā)應(yīng)用程序來說非常有用?!禞ava并發(fā)編程實戰(zhàn)》并不僅是簡單地羅列出各種并發(fā)API以及機制,而是詳細地介紹了許多設(shè)計原則、設(shè)計模式以及思維模式,這些內(nèi)容使得開發(fā)人員更容易構(gòu)建出正確的并且高性能的并發(fā)程序?!禞ava并發(fā)編程實戰(zhàn)》主要內(nèi)容包括:并發(fā)性與線程安全性的基本概念,構(gòu)建以及組合各種線程安全類的技術(shù),使用java.util.concurrent包中的各種井發(fā)構(gòu)建基礎(chǔ)模塊,性能優(yōu)化中的注意事項,如何測試并發(fā)程序,以及一些高級主題,包括原子變量,無阻塞算法及JAVA內(nèi)存模。
圖書封面
圖書標(biāo)簽Tags
無
評論、評分、閱讀與下載