並發編程是Java程式設計師最重要的技能之一,也是最難掌握的一種技能。它要求編程者對計算機最底層的運作原理有深刻的理解,同時要求編程者邏輯清晰、思維縝密,這樣才能寫出高效、安全、可靠的多線程並發程序。
衡量一名「程序猿」的技術實力,一般會看你是否具備深度的系統性能調優的能力。雲計算的時代,對系統的高性能、高並發要求更高。所以,深入了解和掌握Java的多線程機制原理,非常有用,非常必要。
大家都知道並發編程技術就是在同一個處理器上同時的去處理多個任務,充分的利用到處理器的每個核心,最大化的發揮處理器的峰值性能,這樣就可以避免我們因為性能而產生的一些問題。
大廠的核心負載肯定是非常高的,就像阿里巴巴每年都要進行的「雙十一狂歡節」,這麼大的流量負載,並發編程技術在其中就是起到非常大的作用的,歸納一下就是「性能調優」。
今天給大家分享的「Java並發編程寶典」是阿里技術專家/該領域的領軍人物們所撰寫的,可以說是有著絕對性的話語權的。
筆記儘量減少「噦嗦"式的文字語言,全部用Demo式案例來講解技術點的實現,使讀者看到代碼及運行結果後就可以知道此項目要解決的是什麼問題。類似於網絡中Blog的風格,可讓讀者用最短的時間學會此知識點,明白此知識點如何應用,以及在使用時要避免什麼。這就像「瑞士軍刀」,雖短小,卻鋒利。筆記的目的就是幫讀者快速學習並解決問題。
這本書的所有知識均來自於作者多年的項目實踐,傾注了作者多年的心血。講解的深入淺出,讓你掌握起來毫不費力。如果你想成為一名架構師, 如果你想成為一名資深的技術大牛,強烈推薦你讀一讀, 你值得擁有!
讀者對象
筆記特點
內容簡介
第1章Semaphore和Exchanger的使用
類Semaphore的主要作用是限制並發執行的線程個數,它具有synchronized 所不具有的強大功能,比如等待獲得許可的同時可以加入等待時間,還有嘗試是否可以持有鎖等這類擴展功能,可以說Semaphore類是強有力的控制並發線程個數的解決方案之一, 而Exchanger是線程間傳輸數據的方式之一, 而且在傳輸的數據類型上並沒有任何限制。
第2章CountDownLatch和CyclicBarrier的使用
本章主要介紹了CountDownLatch、CyclicBarrier 這兩個類的使用,使用CountDown-Latch類可以實現兩種角色的線程等待對方的效果,而CyclicBarrier類可以使同類線程互相等待達到同步的效果,使用這兩個類可以更加完善地實現線程對象之間的同步性,對線程對象執行的軌跡控制更加方便。
第3章Phaser的使用
類Phaser提供了動態增減parties計數,這點比CyclicBarrier類操作parties更加方便,通過若干個方法來控制多個線程之間同步運行的效果,還可以實現針對某一個線 程取消同步運行的效果,而且支持在指定屏障處等待,在等待時還支持中斷或非中斷等功能,使用Java並發類對線程進行分組同步控制時,Phaser 比CyclicBarrier類功能更加強大,建議使用。
第4章Executor與ThreadPoolExecutor的使用
本章主要介紹ThreadPoolExecutor類的構造方法中各個參數的作用與使用效果,還介紹了Executors 工廠類常用API的使用,也將大部分ThreadPoolExecutor線程池類的常見API一同進行了介紹,並且對ThreadPoolExecutor線程池的拒絕策略進行了實驗,通過使用線程池能最大幅度地減少創建線程對象的內存與CPU開銷,加快程序運行效率,也對創建線程類的代碼進行了封裝,方便開發並發類型的軟體項目。
第5章Future和Callable的使用
本章對Future和Callable接口中的全部API進行了介紹,這兩個接口的優點就是從線程中返回數據以便進行後期的處理,但FutureTask類也有其自身的缺點,就是阻塞性,解決這個缺點請參看第6章。
第6章CompletionSernvice的使用
接口CompletionService完全可以避免FutureTask類阻塞的缺點,可更加有效地處理Future的返回值,也就是哪個任務先執行完,CompletionService 就先取得這個任務的返回值再處理。
第7章接口ExecutorService的方法使用
接口ExecutorService中的方法都以便攜的方式去創建線程池,使用兩個主要的方法invokeAny(和invokeAll0來取得第一個首先執行完任務的結果值,以及全部任務的結果值。
第8章計劃任務ScheduledExecutorService的使用
本章介紹了基於線程池ThreadPoolExecutor的ScheduledThreadPoolExecutor計劃任務執行池對象,使用此類可以高效地實現計劃任務線程池,不再重複創建Thread對象,提高了運行效率。此類也支持間隔運行的功能。
第9章Fork-Join分治編程
在本章主要介紹了Fork-Join 分治編程類主要的API,需要細化掌握ForkJoinTask的2個常用子類的fork分解算法,雖然分治編程可以有效地利用CPU資源,但不要為了分治編程而分治,應該結合具體的業務場景來進行使用。
第10章並發集合框架
本章主要介紹了Java並發包中的集合框架,集合在使用Java語言中是非常重要的技能點,而並發集合框架在原來功能的基礎上進行再次強化,完全支持多線程環境下的數據處理,大大提高了開發效率,有效保證了數據的存儲結構,以常見的阻塞與非阻塞算法加強並發包中功能的可用性。
Java並發編程無處不在,伺服器、資料庫、應用,Java並發是永遠不可跳過的溝坎,優秀的程式設計師一定要在Java並發領域進行煉獄式的學習,吸收消化並最終轉化成軟體產品成果。另外,單純從Java程式設計師成長計劃這方面進行考慮,Java多線程/並發也依然是想深入學習Java必須要掌握的技術,比如在軟體公司中接觸的「緩存」,」分布式一致性」,"高並發框架」,「海量數據處理」,「高效訂單處理」等都與Java多線程、Java並發緊密相關。進行大數據、分布式、高並發類的專題攻克時,並發編程的學習必不可少,但並發編程學習曲線陡峭,多彎路和「坑」。本書基本完全覆蓋了Java並發包中核心類、API與並發框架,最大程度介紹了每個常用類的使用,以案例的方式進行講解,以使讀者快速學習,迅速掌握。
由於內容太多就不一一展示了 ,這4份並發編程手冊分別為226、370、431、422頁,需要完整版的朋友,可以轉發此文關注小編,私信小編【666】來獲取!!
無論如何,開發、測試、調試多線程的程序仍然非常困難:常見的情形總是開發的並發程序看上去可以正常工作,但是在極端情況下就會失敗,就生產環境而言這種情況是指高負載。《JAVA 並發編程實踐》以堅實的理論基礎和翔實的實踐技術,幫助讀者構建可靠的、可伸縮的和可維護的並發應用程式。本書並不是簡單地羅列出並發API和機制,相反,它提供了設計規則、模式和理想模型,使讀者能夠更容易地構建出既正確又高效的並發程序來。
內容簡介
線程安全
一個對象是否應該是線程安全的取決於它是否會被多個線程訪問。線程安全的這個性質,取決於程序中如何使用對象,而不是對象完成了什麼。保證對象的線程安全性需要使用同步來協調對其可變狀態的訪問;若是做不到這一點,就會導致髒數據和其他不可預期的後果。
無論何時,只要有多於一個的線程訪問給定的狀態變量,而且其中某個線程會寫入該變量,此時必須使用同步來協調線程對該變量的訪問。Java 中首要的同步機制是synchronized關鍵字,它提供了獨佔鎖。除此之外,術語「同步」還包括volatile 變量,顯示鎖和原子變量的使用。
你會想到在一些「特殊」情況下上述規則並不適用,不過你應該抵制住這種想法的誘惑。程序如果忽略了必要的同步,可能看上去可以運行,而且能夠通過測試,甚至能正常地運行數年,但它仍然是存在隱患的,任何時刻都有可能崩潰。
共享對象
我們在第2章開始的時候提到過,編寫正確的並發程序的關鍵在於對共享的、可變的狀態進行訪問管理。上一章是關於使用同步來避免多個線程在同一時間訪問同一數據的: 這一章詳細講述共享和發布對象的技術,使多個線程能夠安全地訪問他們。這兩章合在一起,可以作為構建線程安全類,以及使用java.util.concurrent類庫構造安全的並發應用程式的基礎。
組合對象
到目前為止,我們已經介紹了線程安全與同步的基礎知識。但是我們不希望為了獲得線程安全而去分析每次內存訪問;而希望線程安全的組件能夠以安全的方式組合成更大的組件或程序。這一章介紹 了一些構造類的模式,這些模式讓類更容易成為線程安全的,並且不會讓程序意外破壞這些類的線程安全性。
構建塊
上一章探究了一些關於構造線程安全類的技術,包括將線程安全性委託給現有的線程安全類。在實踐中,委託是創建線程安全類最有效的策略之一:只需要用已有的線程安全類來管理所有狀態即可。
任務執行
大多數並發應用程式是圍繞執行任務(ask)進行管理的。所謂任務就是抽象、離散的工作單元(unit of work)。把一個應用程式的工作(work)分離到任務中,可以簡化程序的管理:這種分離還在不同事務間劃分了自然的分界線,可以方便程序在出現錯誤時進行恢復;同時這種分離還可以為並行工作提供一個自然的結構,有利於提高程序的並發性。
取消和關閉
啟動任務和線程都很容易。大多數時候,我們通常允許它們在結束任務後自行停止。但是,有時候我們希望在任務或線程自然結束之前就停止它們,可能因為用戶取消了操作,或者應用程式需要快速關閉。
應用線程池
第6章介紹的任務執行框架,可以簡化任務與線程生命周期的管理。它提供一種簡便、靈活的方式,可以在任務的提交與任務的執行策略之間解耦。第7章包含一些繁雜的細節內容,包括了在真實的應用程式中使用任務執行框架的生命周期服務。本章關注在配置和調整線程池時用的高級選項,講述了使用任務執行框架的過程中需要注意的危險,還提供了一些使用Executor更高級的例子。
GUI應用程式
幾乎所有的GUI工具集都實現為單線程化子系統(single threaded),意味著所有GUI的活動都被限制在一個單 獨的線程中,這其中就包括了Swing和SWT.如果你沒有打算寫一個完全 單線程化的程序,就會有一些活動部分運行在事件線程中, 部分運行在另一個應用程式線程中。像其他與線程相關的bug-一樣, 這種錯誤的分割並不會導致你的應用程式立即崩潰;你的程序會在一些難 以發現的條件下出現古怪的行為.GUI框架自身是單線程子系統,可能你的應用程式還不是,那麼編寫GUI代碼的時候,你需要仔細地考慮線程問題。
避免活躍度危險
安全性和活躍度通常相互牽制。我們使用鎖來保證線程安全,但是濫用鎖可能引起鎖順序死鎖(lock-ordering deadlock)。類似地,我們使用線程池和信號量來約束資源的使用,但是卻不能知曉那些管轄範圍內的活動可能形成的資源死鎖(resource deadlock)。Java應用程式不能從死鎖中恢復,所以確保你的設計能夠避免死鎖出現的先決條件是非常有價值的。這一章將講述一些引發活躍度失敗的原因,以及避免發生這些失敗的方法。
性能和可伸縮性
使用線程最主要的原因是提高性能。使用線程可以使程序更加充分地發揮出閒置的處理能力,從而更好地利用資源:並能夠使程序在現有任務正在運行的情況下立刻開始著手處理新的任務,從而提高系統的響應性。
測試並發程序
並發程序在設計上採用與順序程序大致相同的原則和模式。不同的是並發程序存在定程度的不確定性,順序程序卻沒有這個問題。這樣的不確定性增加了潛在的交互和失敗模式的數量,我們必須為此做好計劃和分析。
顯式鎖
在Java5.0之前,用於調節共享對象訪問的機制只有synchroni zed和volatileeJava5.0提供了新的選擇: ReentrantLock. 與我們已經提到過的機制相反,ReentrantLock並不是作為內部鎖機制的替代,而是當內部鎖被證明受到局限時,提供可選擇的高級特性。
構建自定義的同步工具
類庫中包含了大量依賴於狀態(state -dependent)的類一這些類擁有基於狀態的先驗條件——FutureTask、Semaphore和BlockingQueue。 例如,你不能從一個空隊列中移除條目,也不能從一個尚未結束的任務中獲取結果;在這些操作可以執行前,你必須等到隊列進入「非空」狀態,任務進入「完成」狀態。
原子變量與非阻塞同步機制
java . util. concurrent包中的許多類,比如Semaphore和ConcurrentLinkedQueue,都提供了比使用S)synchronized更好 的性能和可伸縮性。這一章, 我們來學 習這些性能提升的原始來源:原子變量和非阻塞的同步機制。
Java存儲模型
縱觀全書,我們已經最大程度地避開了Java存儲模型(JMM)的底層細節,一直在關注高層的設計問題,比如安全發布、規約,以及遵守同步策略等等。它們的安全性得益於JMM,當你理解了為什麼這些機制會如此工作後,能發現可以更容易有效地使用它們。本章中,我們會揭開Java存儲模型的神秘面紗,看一看它的底層條件和它提供的保證,其間還會涉及一些本書講過的高層設計原則背後的原理。
關注細節求本質,把握機會促發展。
道可頓悟,事須漸修: 一切從基礎做起。一點一滴地慢慢積累。
安全兩字很重要,不能忘記也不能丟。萬一你把它忘了。程序就會出Bug.
知識是學出來的,能力是練出來的。
投入多少,收穫多少:參與多深,領悟多深。
聯強一躍,不能十步,駑馬十駕。功在不舍。
卓越是方向,成就在路上。
不登高山,不知山之高。不臨深淵,不知地之厚也。
鳥欲高飛先展翅,人求上進先讀書。
很多事情不是看到希望了才去堅持,而是堅持了才會看到希望。學習也是如此。
JVM的參數
專家評測
特色
閱讀對象
內容簡介
閱讀本書之前,你必須有-定的Java基礎和開發經驗,最好還有-定的並發編程基礎。如果你是一名並發編程初學者,建議按照順序閱讀本書,並按照書中的例子進行編碼和實戰。如果你有一定的並發編程經驗,可以把本書當做一個手冊, 直接看需要學習的章節。以下是各章節的基本介紹。
第1章並發編程的挑戰
並發編程的目的是為了讓程序運行得更快,但是,並不是啟動更多的線程就能讓程序最大限度地並發執行。在進行並發編程時,如果希望通過多線程執行任務讓程序運行得更快,會面臨非常多的挑戰,比如上下文切換的問題、死鎖的問題,以及受限於硬體和軟體的資源限制問題,本章會介紹幾種並發編程的挑戰以及解決方案。
第2章Java並發機制的底層實現原理
Java代碼在編譯後會變成Java字節碼,字節碼被類加載器加載到JVM裡,JVM執行字節碼,最終需要轉化為彙編指令在CPU上執行,Java中所使用的並發機制依賴於JVM的實現和CPU的指令。本章我們將深入底層-起探索下Java並發機制的底層實現原理。
第3章Java內存模型
Java線程之間的通信對程式設計師完全透明,內存可見性問題很容易困擾Java程式設計師,本章將揭開Java內存模型神秘的面紗。本章大致分4部分:Java內存模型的基礎,主要介紹內存模型相關的基本概念;Java內存模型中的順序-致性,主要介紹重排序與順序一致性內存模型;同步原語,主要介紹3個同步原語(synchronized、volatile和final)的內存語義及重排序規則在處理器中的實現;Java內存模型的設計,主要介紹Java內存模型的設計原理,及其與處理器內存模型和順序一致性內存模型的關係。
第4章Java並發編程基礎
Java從誕生開始就明智地選擇了內置對多線程的支持,這使得Java語言相比同一時期的其他語言具有明顯的優勢。線程作為作業系統調度的最小單元,多個線程能夠同時執行,這將顯著提升程序性能,在多核環境中表現得更加明顯。但是,過多地創建線程和對線程的不當管理也容易造成問題。本章將著重介紹Java並發編程的基礎知識,從啟動一個線程到線程間不同的通信方式,最後通過簡單的線程池示例以及應用(簡單的Web伺服器)來串聯本章所介紹的內容。
第5章Java中的鎖
本章將介紹Java並發包中與鎖相關的API和組件,以及這些API和組件的使用方式和實現細節。內容主要圍繞兩個方面:使用,通過示例演示這些組件的使用方法以及詳細介紹與鎖相關的API;實現,通過分析源碼來剖析實現細節,因為理解實現的細節方能更加得心應手且正確地使用這些組件。希望通過以上兩個方面的講解使開發者對鎖的使用和實現兩個層面有一定的了解。
第6章Java並發容器和框架
Java程式設計師進行並發編程時,相比於其他語言的程式設計師而言要倍感幸福,因為並發編程大師DougLea不遺餘力地為Java開發者提供了非常多的並發容器和框架。本章讓我們一起來見識一下大師操刀編寫的並發容器和框架,並通過每節的原理分析一起來學習如何設計出精妙的並發程序。
第7章Java中的13個原子操作類
因為變量的類型有很多種,所以在Atomic包裡一共提供了13個類,屬於4種類型的原子更,新方式,分別是原子更新基本類型、原子更新數組、原子更新引用和原子更新屬性(欄位)。Atomic包裡的類基本都是使用Unsafe實現的包裝類。
第8章Java中的並發工具類
在JDK的並發包裡提供了幾個非常有用的並發工具類。CountDownL atch、CyclicBarrier和Semaphore工具類提供了一種 並發流程控制的手段,ExchangerI 具類則提供了在線程間交換數據的一種手段。本章會配合-些應用場景來介紹如何使用這些工具類。
第9章Java中的線程池
Java中的線程池是運用場景最多的並發框架,幾乎所有需要異步或並發執行任務的程序都可以使用線程池。在開發過程中,合理地使用線程池能夠帶來3個好處。
還會降低系統的穩定性,使用線程池可以進行統一分配、調優和監控。但是,要做到合理利用線程池,必須對其實現原理了如指掌。
第10章Executor框架
在Java中,使用線程來異步執行任務。Java線程的創建與銷毀需要一定的開銷, 如果我們為每一個任務創建-個新線程來執行,這些線程的創建與銷毀將消耗大量的計算資源。同時,為每一個任務創建-個新線程來執行,這種策略可能會使處於高負荷狀態的應用最終崩潰。
Java的線程既是工作單元,也是執行機制。從JDK 5開始,把工作單元與執行機制分離開來。工作單元包括Runnable和Callable,而執行機制由Executor框架提供。
第11章Java並發編程實踐
當你在進行並發編程時,看著程序的執行速度在自己的優化下運行得越來越快,你會覺得越來越有成就感,這就是並發編程的魅力。但與此同時,並發編程產生的問題和風險可能也會隨之而來。本章先介紹幾個並發編程的實戰案例,然後再介紹如何排查並發編程造成的問題。
本章介紹了使用生產者和消費者模式進行並發編程、線上問題排查手段和性能測試實戰,以及異步任務池的設計。並發編程的實戰需要大家平時多使用和測試,才能在項目中發揮作用
由於內容太多就不一一展示了 ,這4份並發編程手冊分別為226、370、431、422頁,需要完整版的朋友,可以轉發此文關注小編,私信小編【666】來獲取!!
專家評測