這篇博客是開始總結Java併發的開篇,主要說下下面總結Java併發編程相關知識的思路、呈現出本身理解的Java併發知識的全景圖,爲後面Java併發知識總結的複習提供線索和記憶脈絡。主要學習和借鑑的主要資料有:《極客時間》併發編程專欄、《Java併發實戰》等。java
分工:編程
在多核處理器時代,利用多核處理優點,將一個大的任務拆解成一個個小任務分工去完成提升效率。好比要建一條馬路,劃分紅不一樣的任務:打地基、鋪路、鋪磚、土建等不一樣的子任務、分工去完成,提供了工做的效率(性能)。抽象到Java併發上,好比:生產者-消費者模式、Fork/Join、Future(同異步分工協同)等。安全
同步(協做):數據結構
在分工的基礎上,子任務之間可能存在依賴關係,好比在造路過程當中,土建完成以後須要通知鋪路小組去完成鋪路,這就是子任務之間的同步。併發
像這類問題抽象到Java併發上就是:一個線程執行完成了一個任務、如何通知執行後續任務的線程開工的問題。Java提供的Future、同步工具類(CountDownLatch、Notify機制、欄柵CyclicBarrier)等都是解決同步問題的工具。異步
工做中遇到的線程協做問題,基本能夠描述成:當某個條件不知足時,線程須要等待,當某個條件知足時,線程須要被喚醒執行。工具
互斥(安全性):性能
分工、同步主要強調的是性能,而併發程序裏還有一部分關於正確性的的問題,叫「線程安全」。學習
併發程序裏多個線程同時訪問同一個共享變量的時候,結果是不肯定的。不肯定意味着可能正確,也可能錯誤,事先是不不肯定的。而不肯定的主要源頭是可見性問題、有序性問題、和原子性問題。爲了解決這三個問題,Java語言引入內存模型,內存模型提供了一系列的規則,利用這些規則,能夠避免可見性問題、有序性問題,但仍是不足以徹底解決線程安全問題。解決線程安全問題的核心方案仍是互斥。優化
互斥,指同一時刻,只容許一個線程訪問共享變量
互斥的核心就是鎖,Java中的synchronized、SDK裏的各類Lock都能解決互斥問題。雖然說鎖解決了安全問題,但同時也帶來了性能問題,如何保證安全性的同時有能儘量提升性能呢?
能夠分場景優化,Java SDK裏提供ReadWriteLock、StampedLock就能夠優化讀多寫少場景下的鎖性能。固然還可使用無鎖的數據結構,例如Java SDK裏提供的原子類都是基於無鎖技術實現的。
除此以外,還有一些其餘的方案,原理是不共享變量或者變量只容許讀。這方面,Java提供了ThreadLocal和final關鍵字,還有一種Copy-on-write模式。
主要根據《極客時間》併發編程專欄的全景圖的基礎上加上本身的理解補充完善出來的。後面總結主要會圍繞全景圖的脈絡並以全景圖的部分和一個標題分支來命名博客標題。這樣我以爲會更方便記憶和查找。
後面全景圖會根據反覆閱讀《併發編程實戰》來補充更新完善。
全景圖:
基本概念圖:
併發工具圖
(圖片不知道能不能看清楚,思惟導圖附件我會放到個人博客後臺根目錄下的xmind目錄下)。