Java
併發編程對於開發者來講是難點也是重點,想要掌握學會併發編程,並非一件很容易的事情,從本篇文章跟我一塊兒攻克 Java
併發編程JUC
系列教程吧。 JUC
是 java.util.concurrent
的縮寫,其實現參考了 EDU.oswego.cs.dl.util.concurrent
,是 JSR 166
標準規範的一個實現;JSR 166
是一個關於 Java
併發編程的規範提案,在 JDK
中,該規範由java.util.concurrent
包實現。即JUC
是 Java
提供的併發包,其中包含了一些併發編程用到的基礎組件。 JUC
這個包下的類基本上包含了咱們在併發編程時用到的一些工具。大體能夠分爲如下幾類:html
- 原子更新
Java
從JDK1.5
開始提供了java.util.concurrent.atomic
包,方便程序員在多線程環 境下,無鎖的進行原子操做。在Atomic
包裏一共有 12 個類,四種原子更新方式,分別是原子更新基本類型,原子更新 數組,原子更新引用和原子更新字段。 - 鎖和條件變量
java.util.concurrent.locks
包下包含了同步器的框架AbstractQueuedSynchronizer
,基於AQS
構建的Lock
以及與Lock
配合能夠實現等待/通知模式的Condition
。JUC
下的大多數工具類用到了Lock
和Condition
來實現併發。 - 線程池 涉及到的類好比:
Executor
、Executors
、ThreadPoolExector
、AbstractExecutorService
、Future
、Callable
、ScheduledThreadPoolExecutor
等等。 - 阻塞隊列 涉及到的類好比:
ArrayBlockingQueue
、LinkedBlockingQueue
、PriorityBlockingQueue
、LinkedBlockingDeque
等等。 - 併發容器 涉及到的類好比:
ConcurrentHashMap
、CopyOnWriteArrayList
、ConcurrentLinkedQueue
、CopyOnWriteArraySet
等等。 - 同步器 剩下的是一些在併發編程中時常會用到的工具類,主要用來協助線程同步。好比:
CountDownLatch
、CyclicBarrier
、Exchanger
、Semaphore
、FutureTask
等等。 在學習JUC
以前咱們須要瞭解CAS
,AQS
和Unsafe
,對於大部分初學併發編程的同窗這幾個概念容易在腦中混淆,因此先分別說說這幾個概念。 <a name="2Ivdn"></a>
Unsafe
Unsafe
是位於sun.misc
包下的一個類,也是一個不安全的類,爲何會這樣說呢? Java
是一個很是安全的語言, 沒法直接訪問操做系統底層,而是經過本地方法進行訪問,但卻給 Unsafe
類開了「後門」, Unsafe類提供了硬件級別的原子操做,直接訪問操做系統底層,操做內存。開發人員若是不正確的使用,極容易形成程序出錯,程序崩潰等問題。,在平常使用 Unsafe
時必定要慎重。在不理解背後原理其不要使用。在Java 9
中官方提出移除 Sun.misc.Unsafe
, 對於 Java 語言生態應用太廣並未能輕易移除,在 JAVA 9
新增長了 jdk.internal.misc.Unsafe
類來替代前者的功能。後者 不會直接暴露給應用程序。java
此圖來源美團技術團隊:https://tech.meituan.com/2019/02/14/talk-about-java-magic-class-unsafe.html程序員
CAS
Java
提供了非阻塞的volatile
關鍵字來解決共享變量的可見性問題,這在必定程度上彌補了鎖帶來的開銷問題,可是volatile
只能保證共享變量的可見性,不能解決讀—改—寫等的原子性問題。CAS(Compare And Swap
)指比較並交換,是原子操做的一種,可用於在多線程編程中實現不被打斷的數據交換操做,從而避免多線程同時改寫某一數據時因爲執行順序不肯定性以及中斷的不可預知性產生的數據不一致問題。 該操做經過將內存中的值與指定數據進行比較,當數值同樣時將內存中的數據替換爲新的值。JDK裏面的Unsafe類提供了一系列的 compareAndSwap* 方法。CAS
算法CAS(V, E, N)
包含3
個參數,V
表示要更新的變量,E
表示預期的值,N
表示新值。在且僅在V
值等於E
值時,纔會將V
值設爲 N
,若是V
值和 E
值不一樣,則說明已經有其餘線程作了更新,當前線程什麼都不作。最後,CAS
返回當前V的真實值。Concurrent
包下全部類底層都是依靠CAS
操做來實現,而sun.misc.Unsafe
爲咱們提供了一系列的CAS
操做。CAS
會遇到兩個常見的問題?算法
ABA
問題- 自旋問題
此問題放在後面相應的章節講解編程
AQS
AbstractQueuedSynchronizer
抽象同步隊列簡稱AQS
,它是實現同步器的基礎組件,併發包中鎖的底層就是使用AQS
實現的。AQS
定義了一套多線程訪問共享資源的同步框架,許多同步類的實現都依賴於它,例如經常使用的Synchronized
、ReentrantLock
、ReentrantReadWriteLock
、Semaphore
、CountDownLatch
等。該框架下的鎖會先嚐試以CAS
樂觀鎖去獲取鎖,若是獲取不到,則會轉爲悲觀鎖(如RetreenLock
)。數組
總結
本章是併發編程JUC
的開篇,簡單講述了JUC
理論、unsafe
、CAS
、AQS
,後續經過理論+案例
會併發包下進行進一步講解,萬事開頭難,併發編程難學易精。開啓攻克併發編程系列JUC
之路。安全