摘要:耐心看完的你或多或少會有收獲并發(fā)的核心就是包,而的核心是抽象隊列同步器,簡稱,一些鎖啊信號量啊循環(huán)屏障啊都是基于。
耐心看完的你或多或少會有收獲!
Java并發(fā)的核心就是 java.util.concurrent 包,而 j.u.c 的核心是AbstractQueuedSynchronizer抽象隊列同步器,簡稱 AQS,一些鎖啊!信號量??!循環(huán)屏障啊!都是基于AQS。而 AQS 又是基于Unsafe的一系列compareAndSwap,所以理解了這塊,并發(fā)不再是問題!
希望你已經(jīng)了解了 Java內(nèi)存模型
何為 CAS先解釋下何為compareAndSwap,就拿AtomicInteger來舉例了:
// 實(shí)際操作的值 private volatile int value; // value 的偏移量 因?yàn)?int 是32位,知道首部地址就可以了 private static final long valueOffset; // 靜態(tài)初始化塊,通過虛擬機(jī)提供的接口,獲得 valueOffset = 12 // 不論你實(shí)例化多少個 AtomicInteger 對象,這些對象盡管指向不同的堆內(nèi)存,但是結(jié)構(gòu)都是一樣的 // 所以初始化一次就好了 static { try { valueOffset = unsafe.objectFieldOffset (AtomicInteger.class.getDeclaredField("value")); } catch (Exception ex) { throw new Error(ex); } } // 只是個封裝方法,起作用的代碼并不在這 // 值得注意的是顯式的 this 和第三個參數(shù) 1 public final int getAndIncrement() { return unsafe.getAndAddInt(this, valueOffset, 1); } // 以下是 Unsafe 類 可以直接訪問內(nèi)存地址,類似指針,所以不安全 // o 就是 getAndIncrement()傳入的 this,也就是 AtomicInteger 實(shí)例對象 // offset 內(nèi)存首部偏移量 // delta 就是那個 1 // 應(yīng)該是希臘字母 δ /"delt?/ delta 變化量,化學(xué)反應(yīng)中的加熱,屈光度,一元二次方程中的判別式 // 佩服 public final int getAndAddInt(Object o, long offset, int delta) { int v; do { v = getIntVolatile(o, offset); } while (!compareAndSwapInt(o, offset, v, v + delta)); return v; } // 從堆內(nèi)存獲取最新的 value // 如果不明白,可以先了解下 JMM 和 volatile public native int getIntVolatile(Object o, long offset); // expected 就是這個 v = getIntVolatile(o, offset); // 意思就是,我給你這個最新的 value,它要是現(xiàn)在 在內(nèi)存中還是這個值 那你就返回 true,并且把這塊內(nèi)存上值更新為 x // 不然的話,我就一直 while (!compareAndSwapInt(o, offset, v, v + delta)); // 相當(dāng)于自旋鎖 活鎖,不要被高大上的術(shù)語嚇到 就是活的循環(huán),不會像死鎖那樣線程 hang 住 public final native boolean compareAndSwapInt(Object o, long offset, int expected, int x);何為 Lock
知道了CAS就可以進(jìn)一步的說說ReentrantLock, 如果不曾了解Java對象結(jié)構(gòu),建議先了解下 Java 對象的內(nèi)存結(jié)構(gòu)
AQS的幾個子類,由于方法和功能不一,在同步處理的細(xì)節(jié)上可能不一樣。但是,原理都是一樣的,離不開上述的CAS
// 我先簡單解釋一下 synchronized 工作原理 首先它含有 monitorenter 和 monitorexit 兩條指令 // Java 中的每個對象都有自己的 Monitor(由HotSpot c++ 實(shí)現(xiàn)) // 當(dāng)某個線程進(jìn)入加鎖的代碼(實(shí)際上應(yīng)該是拿到被加鎖的對象在內(nèi)存的引用地址) // 會執(zhí)行 monitorenter 然后將 monitor 置為1,當(dāng)其它線程訪問該內(nèi)存時,發(fā)現(xiàn) monitor 不為 0 // 所以其它線程無法獲得 monitor,直到占有 monitor 的線程執(zhí)行 monitorexit 退出將 monitor 減 1 // 如果占有 monitor 的線程重復(fù)進(jìn)入,monitor 是可以一直累加的(可重入鎖,例如通過遞歸或方法互調(diào)) // 了解了 synchronized 基本的工作原理,就會明白為什么會有諸如 nonfairTryAcquire(1) release(1) 的方法 // 這是 AbstractQueuedSynchronizer 類中的字段 // 因?yàn)?ReentrantLock 中的內(nèi)部類 Sync 繼承于 AQS // The synchronization state private volatile int state; // tryLock why ? // 因?yàn)椴煌?synchronized 的悲觀(我才不管你是不是并發(fā),多線程,聲明了,我就加鎖) // 所以 ReentrantLock 我先 try 一 try 吧!萬一不是多線程并發(fā)呢!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/74934.html
摘要:線程池的作用降低資源消耗。通過重復(fù)利用已創(chuàng)建的線程降低線程創(chuàng)建和銷毀造成的資源浪費(fèi)。而高位的部分,位表示線程池的狀態(tài)。當(dāng)線程池中的線程數(shù)達(dá)到后,就會把到達(dá)的任務(wù)放到中去線程池的最大長度。默認(rèn)情況下,只有當(dāng)線程池中的線程數(shù)大于時,才起作用。 線程池的作用 降低資源消耗。通過重復(fù)利用已創(chuàng)建的線程降低線程創(chuàng)建和銷毀造成的資源浪費(fèi)。 提高響應(yīng)速度。當(dāng)任務(wù)到達(dá)時,不需要等到線程創(chuàng)建就能立即執(zhí)行...
摘要:在線程處理任務(wù)期間,其它線程要么循環(huán)訪問,要么一直阻塞等著線程喚醒,再不濟(jì)就真的如我所說,放棄鎖的競爭,去處理別的任務(wù)。寫鎖的話,獨(dú)占寫計數(shù),排除一切其他線程。 回顧 在上一篇 Java并發(fā)核心淺談 我們大概了解到了Lock和synchronized的共同點(diǎn),再簡單總結(jié)下: Lock主要是自定義一個 counter,從而利用CAS對其實(shí)現(xiàn)原子操作,而synchronized是c++...
摘要:比如需要用多線程或分布式集群統(tǒng)計一堆用戶的相關(guān)統(tǒng)計值,由于用戶的統(tǒng)計值是共享數(shù)據(jù),因此需要保證線程安全。如果類是無狀態(tài)的,那它永遠(yuǎn)是線程安全的。參考探索并發(fā)編程二寫線程安全的代碼 線程安全類 保證類線程安全的措施: 不共享線程間的變量; 設(shè)置屬性變量為不可變變量; 每個共享的可變變量都使用一個確定的鎖保護(hù); 保證線程安全的思路: 1. 通過架構(gòu)設(shè)計 通過上層的架構(gòu)設(shè)計和業(yè)務(wù)分析來避...
摘要:基礎(chǔ)問題的的性能及原理之區(qū)別詳解備忘筆記深入理解流水線抽象關(guān)鍵字修飾符知識點(diǎn)總結(jié)必看篇中的關(guān)鍵字解析回調(diào)機(jī)制解讀抽象類與三大特征時間和時間戳的相互轉(zhuǎn)換為什么要使用內(nèi)部類對象鎖和類鎖的區(qū)別,,優(yōu)缺點(diǎn)及比較提高篇八詳解內(nèi)部類單例模式和 Java基礎(chǔ)問題 String的+的性能及原理 java之yield(),sleep(),wait()區(qū)別詳解-備忘筆記 深入理解Java Stream流水...
閱讀 1772·2021-11-18 13:20
閱讀 1163·2021-10-11 10:59
閱讀 2995·2021-08-24 10:01
閱讀 3509·2019-08-29 14:21
閱讀 3359·2019-08-29 14:15
閱讀 3527·2019-08-26 12:23
閱讀 3348·2019-08-26 11:46
閱讀 3355·2019-08-26 11:35