全棧知識(shí)點(diǎn)
關(guān)鍵字: synchronized詳解 | Java 全棧知識(shí)體系
1.java反射機(jī)制
1.1 類(lèi)加載過(guò)程
1.1.1 類(lèi)的加載過(guò)程:
源文件經(jīng)過(guò)編譯后得到.class文件立美,被jvm加到內(nèi)存中帕翻,在運(yùn)行時(shí)加載和執(zhí)行;
加載過(guò)程:加載——連接(驗(yàn)證——準(zhǔn)備——解析)——初始化
1.1.2 雙親委派模型:
加載時(shí)自下往上獲取類(lèi)是否加載昌妹,加載時(shí)從上往下嘗試加載甘凭,保證類(lèi)只被加載一次稀拐,運(yùn)行期間一個(gè)類(lèi)只有一個(gè)class對(duì)象產(chǎn)生;
Bootstrap ClassLoader啟動(dòng)類(lèi)加載器
Extension ClassLoader擴(kuò)展類(lèi)加載器
App ClassLoader應(yīng)用程序類(lèi)加載器
繼承ClassLoader自定義類(lèi)加載器
靜態(tài)加載和動(dòng)態(tài)加載:
new()初始化一個(gè)類(lèi)視為靜態(tài)加載丹弱,加載時(shí)異常是error,NoClassDefFoundError德撬;
class.forName()視為動(dòng)態(tài)加載(運(yùn)行時(shí)可改變程序結(jié)構(gòu)和變量類(lèi)型)铲咨,加載時(shí)異常ClassNotFoundException,checked異常蜓洪,寫(xiě)代碼時(shí)需要catch
1.2.java反射機(jī)制
反射機(jī)制:運(yùn)行時(shí)可獲取任何一個(gè)類(lèi)的方法和屬性纤勒,可調(diào)用任何對(duì)象的方法和屬性
反射獲取屬性和方法:
1.object——getClass,需要已經(jīng)有類(lèi)的對(duì)象存在隆檀;
2.靜態(tài)的class屬性摇天,如String.class,可返回相關(guān)聯(lián)的class對(duì)象,不需要類(lèi)的對(duì)象存在恐仑;
3.class類(lèi)的靜態(tài)方法forName(String className)? --className為全路徑包名
通過(guò)反射生成對(duì)象:
1.class對(duì)象的newInstance()
2.通過(guò)class對(duì)象——Constructor對(duì)象——Constructor的newInstance()創(chuàng)建對(duì)象 -- 可指定構(gòu)造器類(lèi)的實(shí)例泉坐,newInstance()方法的本質(zhì)是調(diào)用類(lèi)的無(wú)參Public構(gòu)造方法
獲取某個(gè)類(lèi)的構(gòu)造方法 getDeclaredConstructor(不分public);
獲取類(lèi)的成員方法: getMethod()裳仆,getDeclaredMethod(不分public)
獲取類(lèi)的成員變量(成員屬性:getDeclaredField(不分public)腕让,獲取私有setAccessible(true)
java基礎(chǔ)之反射機(jī)制_悟笙的博客-CSDN博客_java 反射
Java基礎(chǔ)篇:反射機(jī)制詳解_張維鵬的博客-CSDN博客_java反射機(jī)制原理詳解
Java虛擬機(jī):對(duì)象創(chuàng)建過(guò)程與類(lèi)加載機(jī)制、雙親委派模型_張維鵬的博客-CSDN博客
3.AQS(AbstractQuenedSynchronizer 抽象的隊(duì)列式同步器)
3.1.核心思想:
被請(qǐng)求的共享資源空閑——當(dāng)前請(qǐng)求資源的線(xiàn)程設(shè)置為有效鉴逞,共享資源設(shè)置為鎖定狀態(tài)记某;
如果被請(qǐng)求的共享資源被占用——線(xiàn)程阻塞等待,被喚醒時(shí)鎖分配的機(jī)制构捡,用CLH隊(duì)列(虛擬雙向隊(duì)列液南,無(wú)隊(duì)列實(shí)例,通過(guò)節(jié)點(diǎn)關(guān)聯(lián))鎖實(shí)現(xiàn)勾徽;
volatile修飾共享變量state滑凉,線(xiàn)程通過(guò)CAS去改變狀態(tài)符,成功則獲取鎖成功喘帚,失敗則進(jìn)入等待隊(duì)列畅姊,等待被喚醒;
3.2.資源共享方式:
獨(dú)占式:exclusive, 只有ReentrantLock可以執(zhí)行吹由;
共享:share,有CountDownLatch若未、ReadWriteLock等可以執(zhí)行;
同時(shí)實(shí)現(xiàn)獨(dú)占和共享兩種方式:如ReentrantReadWriteLock倾鲫;
AQS詳解(面試)_mulinsen77的博客-CSDN博客_aqs
可重入鎖粗合,共享模式,互斥鎖(源碼解析)
Java并發(fā)之AQS詳解 - waterystone - 博客園
LockSupport:
阻塞park(),釋放unpark()乌昔,無(wú)先后順序隙疚,permit只有0和1,多次park()不會(huì)累加磕道;
syncronized:
等待wait(), 喚醒notify(),成對(duì)出現(xiàn)供屉,有先后順序,通過(guò)底層monitor對(duì)象完成,
? ??不需要手動(dòng)釋放鎖伶丐,
? ??非公平鎖悼做,不可中斷,
? ? 喚醒機(jī)制:隨機(jī)喚醒或者全部喚醒(notifyAll())撵割;
作用域
不能被繼承
加在對(duì)象時(shí)贿堰,同步的對(duì)象是實(shí)例,同步的是非靜態(tài)方法
加在類(lèi)XXXX.class或者代碼塊(方法)(可以對(duì)靜態(tài)方法同步
synchronized 作用域問(wèn)題_程序媛-CSDN博客_synchronized作用域
深入分析Synchronized原理(阿里面試題) - aspirant - 博客園
synchronized的四種作用域以及不能被繼承解析 - 從此寂靜無(wú)聲 - 博客園
ReentrantLock:
Sync類(lèi)實(shí)現(xiàn)啡彬,需要手動(dòng)釋放鎖
? ??可設(shè)置羹与,true 公平鎖(FIFO),false非公平鎖
? ??可中斷庶灿,中斷方法:
? ? tryLock(long timeout TimeUnit unit)纵搁,
????lockInterruptibly()放代碼塊中調(diào)用,調(diào)用interrupt方法可中斷
? ?喚醒機(jī)制: 可設(shè)置條件精準(zhǔn)喚醒往踢,前驅(qū)節(jié)點(diǎn)的出隊(duì)或阻塞線(xiàn)程被中斷
深入理解 AQS 底層實(shí)現(xiàn)原 park unpar理_庸人庸的博客-CSDN博客_aqs
ReentrantLock公平鎖和非公平鎖加鎖和釋放過(guò)程(源碼解析和流程圖講解比較清晰)
對(duì)比:
相同:可協(xié)調(diào)多線(xiàn)程同步腾誉;互斥鎖和可見(jiàn);可重入鎖
不同:
1. ReentrantLock顯示地獲得峻呕,釋放鎖利职,synchronized隱式獲得釋放鎖
2. ReentrantLock可響應(yīng)中斷,可輪回瘦癌,synchronized是不可以響應(yīng)中斷的
3. ReentrantLock是API級(jí)別的猪贪,synchronized是JVM級(jí)別的
4. ReentrantLock可以實(shí)現(xiàn)公平鎖
5. ReentrantLock通過(guò)Condition可以綁定多個(gè)條件
6. 底層實(shí)現(xiàn)不一樣,synchronized是同步阻塞讯私,使用的是悲觀并發(fā)策略热押,lock是同步非阻塞,采用的是樂(lè)觀并發(fā)策略斤寇。
7. Lock是一個(gè)接口桶癣,而synchronized是java中的關(guān)鍵字,synchronized是內(nèi)置的語(yǔ)言實(shí)現(xiàn)
8. synchronized 在發(fā)生異常時(shí)娘锁,會(huì)自動(dòng)釋放線(xiàn)程占有的鎖牙寞,因此不會(huì)導(dǎo)致死鎖現(xiàn)象發(fā)生;而 Lock 在發(fā)生異常時(shí)莫秆,如果沒(méi)有主動(dòng)通過(guò) unLock()去釋放鎖碎税,則很可能造成死鎖現(xiàn)象, 因此使用 Lock 時(shí)需要在 finally 塊中釋放鎖馏锡。
synchronized和ReentrantLock的區(qū)別_淮水竹亭-CSDN博客
java面試題:java中斷,synchronized和ReentrantLock能否中斷_我是方小磊的博客-CSDN博客_reentrantlock中斷
3.3.CAS底層原理:
比較交換技術(shù)伟端,內(nèi)存地址V杯道,期望值E,新值N,經(jīng)過(guò)對(duì)比期望值與 V党巾,決定是否交換萎庭,相等將N更新
a-B-a問(wèn)題,添加version版本號(hào)控制
多次比較效率低齿拂,某個(gè)線(xiàn)程取值與期望值一直不相等可能無(wú)限循環(huán)
1)確保對(duì)內(nèi)存的讀-改-寫(xiě)操作原子執(zhí)行驳规。處理器會(huì)使用總線(xiàn)鎖 或 緩存鎖來(lái)保持原子性。
2)禁止該指令署海,與之前和之后的讀和寫(xiě)指令重排序吗购。
3)把CPU寫(xiě)緩沖區(qū)中的所有數(shù)據(jù)刷新到內(nèi)存中,使其它CPU緩存失效砸狞。
深入圖解AQS實(shí)現(xiàn)原理和源碼分析_Seky_fei的博客-CSDN博客
CAS原理解析 CAS底層 - YoungDeng - 博客園
5.java多線(xiàn)程并發(fā)
Java中如何保證線(xiàn)程安全性_阿梨喜歡吃榴蓮的博客-CSDN博客_如何保證線(xiàn)程安全
如何確保線(xiàn)程安全_笑笑生的博客-CSDN博客_怎么確保線(xiàn)程安全
5.1 final原理:
修飾的是一個(gè)基本數(shù)據(jù)類(lèi)型數(shù)據(jù):這個(gè)數(shù)據(jù)的值在初始化后將不能被改變;捻勉;
當(dāng)final修飾的是一個(gè)引用類(lèi)型數(shù)據(jù)時(shí):也就是修飾一個(gè)對(duì)象時(shí), 引用在初始化后將永遠(yuǎn)指向一個(gè)內(nèi)存地址, 不可修改. 但是該內(nèi)存地址中保存的對(duì)象信息可以修改的
修飾的類(lèi)時(shí),該類(lèi)不可被繼承刀森,該類(lèi)的方法隱式指定為final方法踱启;
修飾方法時(shí),該方法不能被重寫(xiě)
深入理解final關(guān)鍵字(詳解)_念念不忘研底,必有回響-CSDN博客_final關(guān)鍵字
淺析Java中的final關(guān)鍵字 - Matrix海子 - 博客園
5.2 volatile原理:
共享和防止指令重排序埠偿,但是不能保證原子性
lock指令:
????鎖總線(xiàn),其它CPU對(duì)內(nèi)存的讀寫(xiě)請(qǐng)求都會(huì)被阻塞榜晦,直到鎖釋放冠蒋,不過(guò)實(shí)際后來(lái)的處理器都采用鎖緩存替代鎖總線(xiàn);
????lock后的寫(xiě)操作會(huì)回寫(xiě)已修改的數(shù)據(jù)芽隆,同時(shí)讓其它CPU相關(guān)緩存行失效浊服,從而重新從主存中加載最新的數(shù)據(jù)
可見(jiàn)性:寫(xiě)操作StoreStore屏障,寫(xiě)操作之后StoreLoad胚吁,將最新變量刷回內(nèi)存;讀之前l(fā)oad讀取主內(nèi)存的最新變量牙躺,讀之后LoadLoad和LoadStore內(nèi)存屏障
深入理解Volatile關(guān)鍵字及其實(shí)現(xiàn)原理_澤宇的博客-CSDN博客
Volatile禁止指令重排序(三) - MXC肖某某 - 博客園
volatile是怎么保障內(nèi)存可見(jiàn)性以及防止指令重排序的?_做最亮的星星-CSDN博客_volatile如何保證內(nèi)存可見(jiàn)性
atomicLong:對(duì)長(zhǎng)整形進(jìn)行原子操作
incrementAndGet()
volatile修飾value 腕扶,CAS更改
volatile和Atomic_dzyls的筆記-CSDN博客
Java原子類(lèi)--AtomicLong - ken007 - 博客園
5.3 線(xiàn)程池
線(xiàn)程的生命周期:創(chuàng)建start——就緒runnable(阻塞)——run——stop
方便線(xiàn)程的管理孽拷,可以根據(jù)系統(tǒng)的承受能力,調(diào)整線(xiàn)程池中工作線(xiàn)線(xiàn)程的數(shù)目半抱,防止因?yàn)橄倪^(guò)多的內(nèi)存脓恕,減少創(chuàng)建和銷(xiāo)毀的內(nèi)存開(kāi)銷(xiāo)
ThreadPoolExecutor
核心線(xiàn)程數(shù)量corePoolSize
最大線(xiàn)程數(shù)量maximumPoolSize
keepAliveTime:核心線(xiàn)程以外的線(xiàn)程回收時(shí)間設(shè)置
workQueue:FIFIO原則(先進(jìn)先出)
? ??SynchronousQueue 直接提交:該QUEUE中,每個(gè)插入操作必須等待另一個(gè)線(xiàn)程的對(duì)應(yīng)移除操作窿侈。
? ??LinkedBlockingQueue 無(wú)界隊(duì)列:所有corePoolSize?線(xiàn)程都忙時(shí)新任務(wù)在隊(duì)列中等待炼幔。這樣,創(chuàng)建的線(xiàn)程就不會(huì)超過(guò)?corePoolSize
? ??ArrayBlockingQueue 有界隊(duì)列 不推薦
handler:拒絕策略
? ??RejectedExecutionHandler:拒絕四種策略
? ?1.?CallerRunsPolicy:線(xiàn)程調(diào)用運(yùn)行該任務(wù)的?execute本身史简。此策略提供簡(jiǎn)單的反饋控制機(jī)制乃秀,能夠減緩新任務(wù)的提交速度;
????2.AbortPolicy:處理程序遭到拒絕將拋出運(yùn)行時(shí)RejectedExecutionException
? ? 3.DiscardPolicy:刪除,但是不拋出異常
? ? 4.DiscardOldestPolicy:如果執(zhí)行程序尚未關(guān)閉跺讯,則位于工作隊(duì)列頭部的(等待時(shí)間最久)任務(wù)將被刪除枢贿,然后重試執(zhí)行程序(如果再次失敗,則重復(fù)此過(guò)程)
線(xiàn)程池的原理及實(shí)現(xiàn)_康志的博客-CSDN博客_線(xiàn)程池的原理
Java線(xiàn)程池的底層實(shí)現(xiàn)與使用 - StoneGeek - 博客園
深入理解線(xiàn)程和線(xiàn)程池(圖文詳解)_weixin_40271838的博客-CSDN博客_線(xiàn)程池
線(xiàn)程池的工作原理與源碼解讀 - 清泉^_^ - 博客園
5.4 線(xiàn)程的銷(xiāo)毀
核心線(xiàn)程超時(shí)刪除:allowCoreThreadTimeOut=true
1當(dāng)沒(méi)有超過(guò)核心線(xiàn)程時(shí)刀脏,不會(huì)銷(xiāo)毀線(xiàn)程
2當(dāng)超過(guò)核心線(xiàn)程數(shù):再判斷局荚,如果超過(guò)最大值,則銷(xiāo)毀愈污;如果timeout過(guò)耀态,則銷(xiāo)
java 線(xiàn)程池 配置_Java手動(dòng)配置線(xiàn)程池過(guò)程詳解_馬斯克·賈的博客-CSDN博客
Java線(xiàn)程池的allowCoreThreadTimeOut參數(shù)_weixin_33859231的博客-CSDN博客
6.redis
6.1 分布式鎖:
保證同一時(shí)間只能有一個(gè)客戶(hù)端對(duì)共享資源進(jìn)行操作允懂,解決多個(gè)服務(wù)資源共享的問(wèn)題
標(biāo)志位(唯一標(biāo)識(shí))+超時(shí)設(shè)置+finally釋放鎖
【劍指Offer】Redis 分布式鎖的實(shí)現(xiàn)原理看這篇就夠了_龍臺(tái)的技術(shù)筆記-CSDN博客_redis分布式鎖實(shí)現(xiàn)原理
Redis實(shí)現(xiàn)分布式鎖原理與實(shí)現(xiàn)分析_jp413670706的專(zhuān)欄-CSDN博客_redis分布式鎖實(shí)現(xiàn)原理
基礎(chǔ)信息:
主要依賴(lài)物理內(nèi)存送挑,一個(gè)字符串類(lèi)型最大容量512M
數(shù)據(jù)類(lèi)型:String、List逃延、Set擎析、Sorted Set簿盅、hashes
史上最全Redis面試題及答案_xiaozhegaa的博客-CSDN博客_redis面試題及答案
zset:
redis zset底層實(shí)現(xiàn)原理 - YF-海納百川 - 博客園
Redis有序集合zset的底層實(shí)現(xiàn) - 簡(jiǎn)書(shū)
6.2 持久化:
RDB機(jī)制:
save操作同步或者設(shè)置定時(shí)自動(dòng)觸發(fā)
在指定的時(shí)間間隔內(nèi)生成數(shù)據(jù)集的時(shí)間點(diǎn)快照
(1)RDB文件緊湊,全量備份揍魂,非常適合用于進(jìn)行備份和災(zāi)難恢復(fù)桨醋。
(2)生成RDB文件的時(shí)候,redis主進(jìn)程會(huì)fork()一個(gè)子進(jìn)程來(lái)處理所有保存工作现斋,主進(jìn)程不需要進(jìn)行任何磁盤(pán)IO操作喜最。
(3)RDB 在恢復(fù)大數(shù)據(jù)集時(shí)的速度比 AOF 的恢復(fù)速度要快。
一次全量備份庄蹋,存儲(chǔ)的是內(nèi)存數(shù)據(jù)的二進(jìn)制序列化形式瞬内,存儲(chǔ)上非常緊湊,快照時(shí)父線(xiàn)程修改的數(shù)據(jù)可能無(wú)法保存
AOF機(jī)制:
修改時(shí)觸發(fā)限书;異步虫蝶,每秒觸發(fā);從不觸發(fā)
?持久化記錄服務(wù)器執(zhí)行的所有寫(xiě)操作命令
(1)可以更好的保護(hù)數(shù)據(jù)不丟失倦西,一般AOF會(huì)每隔1秒能真,通過(guò)一個(gè)后臺(tái)線(xiàn)程執(zhí)行一次fsync操作,最多丟失1秒鐘的數(shù)據(jù)扰柠;
(2)AOF日志文件沒(méi)有任何磁盤(pán)尋址的開(kāi)銷(xiāo)粉铐,寫(xiě)入性能非常高,文件不容易破損
(3)日志文件即使過(guò)大的時(shí)候卤档,出現(xiàn)后臺(tái)重寫(xiě)操作蝙泼,也不會(huì)影響客戶(hù)端的讀寫(xiě)
(4)AOF日志文件的命令通過(guò)非常可讀的方式進(jìn)行記錄劝枣,這個(gè)特性非常適合做災(zāi)難性的誤刪除的緊急恢復(fù)
Redis的兩種持久化RDB和AOF(超詳細(xì))_鯊魚(yú)辣椒灬的博客-CSDN博客_rdb和aof
https://baijiahao.baidu.com/s?id=1654694618189745916&wfr=spider&for=pc
6.3 緩存更新策略
內(nèi)存溢出淘汰策略:
過(guò)期策略:過(guò)期踱承;定時(shí)
Redis 緩存更新策略_愛(ài)與不愛(ài)倡缠,一念之間-CSDN博客_redis 更新策略
6.4 redis集群:
主從模式:master提供讀寫(xiě)服務(wù),寫(xiě)操作后同步內(nèi)存到slave茎活,slave只提供讀服務(wù),master掛掉停止寫(xiě)服務(wù)
哨兵模式:master掛掉后琢唾,會(huì)從其他slave選擇新的master载荔,每個(gè)sentinel以每秒鐘一次的頻率向它所知的master,slave以及其他sentinel實(shí)例發(fā)送一個(gè) PING 命令
cluster模式:
Redis集群詳解_變成習(xí)慣-CSDN博客_redis集群
7.hashMap
7.1 基本原理:
數(shù)組和鏈表的結(jié)合采桃,解決修改和查找效率問(wèn)題懒熙,對(duì)象entry(包含key,value)普办,1.8后采用Node數(shù)組工扎;
? ? 存儲(chǔ)時(shí):object.hasncode()獲取hashcode(一般的Hash函數(shù)為:要存入的數(shù) mod(求余) Hash數(shù)組長(zhǎng)度),當(dāng)hashcode相同時(shí)衔蹲,存儲(chǔ)在bucket鏈表的下一個(gè)節(jié)點(diǎn)肢娘;
? ??取模:是(table.length - 1) & hash,算法直接舍棄了二進(jìn)制hash值在table.length以上的位舆驶,因?yàn)槟切┪欢即韙able.length的2的n次方倍數(shù)橱健。取模的結(jié)果就是Node將要放入table的下標(biāo)。
????獲取值時(shí):調(diào)用get(key)方法沙廉,通過(guò)鍵對(duì)象的hashcode找到bucket位置拘荡,再調(diào)用keys.equals()方法;
????put()方法:第一次initTable()初始化table撬陵,長(zhǎng)度是 16珊皿,計(jì)算hash找到位置,通過(guò)cas方法加入節(jié)點(diǎn)巨税;如果table不為空蟋定,hash=i,table[i]為node垢夹,遍歷鏈表查找是否有相同的hash值溢吻,如有相同hash值替換新的節(jié)點(diǎn),如果沒(méi)有直接插入新節(jié)點(diǎn)果元;table[i]為treenode促王,紅黑樹(shù)鏈表
? ? 擴(kuò)容:懶加載機(jī)制(使用才加載),默認(rèn)大小為16而晒,負(fù)載因子大小為0.75蝇狼,到達(dá)大小時(shí)進(jìn)行rehashing過(guò)程,用散列擴(kuò)容2倍倡怎,鏈表長(zhǎng)度>8&&數(shù)組的長(zhǎng)度>=64——轉(zhuǎn)變?yōu)榧t黑樹(shù)迅耘,根據(jù)hash值分為兩個(gè)子鏈表;
equals結(jié)果為true的hashcode一定一樣贱枣,為false的hashcode可能一樣
7.2 如何減少hash碰撞:
使用String和Integer這wrapper類(lèi),尤其String類(lèi)颤专,final不可變纽哥,且重寫(xiě)了equals和hashcode()方法;
拉鏈法:目前hashmap使用的方法
rehash:哈希函數(shù),二次哈希函數(shù),,,
開(kāi)放地址法:(h(key)+di) mod m(鏈表長(zhǎng)度)栖秕,di取值 1 2 3 ... m-1春塌,線(xiàn)性探測(cè)再散列;di=1簇捍,每次沖突后后移一位只壳,di=1 -1 2 -2 4 -4 9 -9? ...k*k? -k*k(k<m/2),二次探測(cè)再散列;di取值可能為偽隨機(jī)數(shù)列暑塑,稱(chēng)偽隨機(jī)探測(cè)再散列
公共溢出區(qū):記載沖突的點(diǎn)
負(fù)載因子調(diào)整
解決Hash碰撞沖突方法總結(jié)_lppl010_的專(zhuān)欄-CSDN博客_hash碰撞解決方法
7.3 線(xiàn)程安全問(wèn)題
hashtable對(duì)比:
? ? hasnhmap:元素?zé)o序吼句,key可以為null, 線(xiàn)程不安全(Map m = Collections.synchronizeMap(hashMap);)事格,效率高惕艳,
? ? hashtable:元素有序,key不可為null分蓖, 線(xiàn)程安全(內(nèi)部有synchronized)尔艇,效率低?
ConcurrentHashMap
1.初始化table:size標(biāo)志位,yield(),cas放置Node
2.put()空節(jié)點(diǎn)null:cas,volatile
3.put()節(jié)點(diǎn):cas,對(duì)當(dāng)前節(jié)點(diǎn)sychronized
4.擴(kuò)容:hash占位Node-1=MOVED,擴(kuò)容時(shí)可參與幫助擴(kuò)容
?key不可為null,table數(shù)組元素作為鎖么鹤,對(duì)每一行數(shù)據(jù)進(jìn)行加鎖终娃,并發(fā)控制使用Synchronized和CAS來(lái)操作;
HashMap底層實(shí)現(xiàn)原理及面試問(wèn)題_瘋一樣的女子-CSDN博客_hashmap底層實(shí)現(xiàn)原理
ConcurrentHashMap是如何實(shí)現(xiàn)線(xiàn)程安全的_|-| [- |_ |_ ()-CSDN博客_concurrenthashmap如何保證線(xiàn)程安全
HashMap的底層實(shí)現(xiàn)原理 - auldlangsynezh - 博客園
1.8的hashMap源碼解析和紅黑樹(shù)
????volatile V val; // get操作全程不需要加鎖是因?yàn)镹ode的成員val是用volatile修飾
? ? volatile Node<K,V> next;? ? //Node<k,v>[] table,實(shí)現(xiàn)了Entry接口,表示鏈表中的下一個(gè)節(jié)點(diǎn),數(shù)組用volatile修飾主要是保證在數(shù)組擴(kuò)容的時(shí)候保證可見(jiàn)性;
????setValue用final修飾
紅黑樹(shù)查找O(logn)
紅黑樹(shù)通過(guò)treemap(有序)實(shí)現(xiàn)
Java中HashMap底層實(shí)現(xiàn)原理(JDK1.8)源碼分析_tuke_tuke的博客-CSDN博客_hashmap底層實(shí)現(xiàn)原理
逐行解讀HashMap源碼之紅黑樹(shù)篇_節(jié)點(diǎn)
7.4 JDK1.8的改動(dòng)點(diǎn):
1蒸甜、JDK1.7版本鎖的粒度是基于Segment的棠耕,包含多個(gè)HashEntry,而JDK1.8實(shí)現(xiàn)降低鎖的粒度就是HashEntry(首節(jié)點(diǎn))
2柠新、JDK1.8版本的數(shù)據(jù)結(jié)構(gòu)變得更加簡(jiǎn)單窍荧,去掉了Segment這種數(shù)據(jù)結(jié)構(gòu),使用synchronized來(lái)進(jìn)行同步鎖粒度降低恨憎,所以不需要分段鎖的概念蕊退,實(shí)現(xiàn)的復(fù)雜度也增加了
3、JDK1.8使用紅黑樹(shù)來(lái)優(yōu)化鏈表憔恳,基于長(zhǎng)度很長(zhǎng)的鏈表的遍歷是一個(gè)很漫長(zhǎng)的過(guò)程瓤荔,而紅黑樹(shù)的遍歷效率是很快的,代替一定閾值的鏈表钥组,這樣形成一個(gè)最佳拍檔
4输硝、JDK1.8為什么使用內(nèi)置鎖synchronized來(lái)代替重入鎖ReentrantLock:
- 低粒度加鎖方式,synchronized并不比ReentrantLock差程梦,
粗粒度加鎖中ReentrantLock可能通過(guò)Condition來(lái)控制各個(gè)低粒度的邊界点把,更加的靈活橘荠,而在低粒度中,Condition的優(yōu)勢(shì)就沒(méi)有了
- 在大量的數(shù)據(jù)操作下郎逃,對(duì)于JVM的內(nèi)存壓力哥童,基于API的ReentrantLock會(huì)開(kāi)銷(xiāo)更多的內(nèi)存
某個(gè)節(jié)點(diǎn)的hash值是MOVED,則表示正在進(jìn)行數(shù)組擴(kuò)張的數(shù)據(jù)復(fù)制階段
ConcurrentHashMap實(shí)現(xiàn)原理及源碼分析_快樂(lè)小石頭的博客-CSDN博客_concurrenthashmap實(shí)現(xiàn)原理
7.5 擴(kuò)容機(jī)制
Hashmap實(shí)現(xiàn)原理及擴(kuò)容機(jī)制詳解_lkforce-CSDN博客_hashmap擴(kuò)容
8.設(shè)計(jì)模式
8.1 單例模式
1.單例類(lèi)只有一個(gè)實(shí)例對(duì)象褒翰;
2.該單例對(duì)象必須由單例類(lèi)自行創(chuàng)建如蚜;
3.單例類(lèi)對(duì)外提供一個(gè)訪(fǎng)問(wèn)該單例的全局訪(fǎng)問(wèn)點(diǎn)。
懶漢式和餓漢式影暴,包括線(xiàn)程安全和不安全的實(shí)現(xiàn)
8.1.1 懶漢式線(xiàn)程安全實(shí)現(xiàn):
1.初始化變量用volatile修飾Singleton instance;(其中volatile作用是禁止指令重排序)
2.雙重檢驗(yàn)鎖模式(double checked locking pattern):是一種使用同步塊加鎖的方法,稱(chēng)為雙重檢查鎖探赫,因?yàn)闀?huì)有兩次檢查?instance == null型宙,一次是在同步塊外,一次是在同步塊內(nèi)伦吠;
8.1.2餓漢式線(xiàn)程安全實(shí)現(xiàn)方式:
1.初始化變量用final修飾
2.內(nèi)部靜態(tài)類(lèi)
3.枚舉
如何正確地寫(xiě)出單例模式 | Jark's Blog
8.2.設(shè)計(jì)模式基礎(chǔ)
設(shè)計(jì)原則:可復(fù)用妆兑,可擴(kuò)展,可維護(hù)
開(kāi)閉原則:對(duì)擴(kuò)開(kāi)放毛仪,對(duì)修改關(guān)閉搁嗓;實(shí)現(xiàn):抽象約束,封裝變化
里式替換原則:繼承必須確保超類(lèi)所擁有的性質(zhì)在子類(lèi)中仍然成立
依賴(lài)倒置原則:要面向接口編程箱靴,不要面向?qū)崿F(xiàn)編程腺逛。
Java設(shè)計(jì)模式:23種設(shè)計(jì)模式全面解析(超級(jí)詳細(xì))
8.3?工廠(chǎng)模式
靜態(tài)工廠(chǎng)模式(簡(jiǎn)單工廠(chǎng)模式):通過(guò)向工廠(chǎng)傳遞類(lèi)型來(lái)指定要?jiǎng)?chuàng)建的對(duì)象
一般工廠(chǎng)模式:抽象工廠(chǎng),具體工廠(chǎng)衡怀,抽象產(chǎn)品棍矛,具體產(chǎn)品,將生產(chǎn)任務(wù)交給不同的派生類(lèi)工廠(chǎng)抛杨。這樣不用通過(guò)指定類(lèi)型來(lái)創(chuàng)建對(duì)象了
抽象工廠(chǎng)模式:通過(guò)在AbstarctFactory中增加創(chuàng)建產(chǎn)品的接口够委,并在具體子工廠(chǎng)中實(shí)現(xiàn)新加產(chǎn)品的創(chuàng)建,當(dāng)然前提是子工廠(chǎng)支持生產(chǎn)該產(chǎn)品怖现。否則繼承的這個(gè)接口可以什么也不干
由于可能封裝了大量對(duì)象和工廠(chǎng)創(chuàng)建茁帽,新加產(chǎn)品需要修改已定義好的工廠(chǎng)相關(guān)的類(lèi),因此對(duì)于產(chǎn)品和工廠(chǎng)的擴(kuò)展不太友好
設(shè)計(jì)模式之工廠(chǎng)模式(factory pattern) - alpha_panda - 博客園
8.4 動(dòng)態(tài)代理
代理模式:為其他類(lèi)提供一個(gè)代理來(lái)控制對(duì)某個(gè)對(duì)象的訪(fǎng)問(wèn)屈嗤,代理類(lèi)負(fù)責(zé)為委托類(lèi)預(yù)處理消息潘拨,過(guò)濾消息并轉(zhuǎn)發(fā)消息,以及進(jìn)行消息被委托類(lèi)執(zhí)行后的后續(xù)處理
程序運(yùn)行的過(guò)程中恢共,根據(jù)被代理的接口來(lái)動(dòng)態(tài)生成代理類(lèi)的class文件战秋,并加載運(yùn)行的過(guò)程
1.創(chuàng)建一個(gè)實(shí)現(xiàn)接口InvocationHandler的類(lèi),它必須實(shí)現(xiàn)invoke方法
2.創(chuàng)建被代理的類(lèi)以及接口
3.通過(guò)Proxy的靜態(tài)方法newProxyInstance(ClassLoaderloader, Class[] interfaces, InvocationHandler h)創(chuàng)建一個(gè)代理
4.通過(guò)代理調(diào)用方法
細(xì)說(shuō)JDK動(dòng)態(tài)代理的實(shí)現(xiàn)原理_癡人說(shuō)夢(mèng)-CSDN博客_jdk動(dòng)態(tài)代理
Java JDK 動(dòng)態(tài)代理(AOP)使用及實(shí)現(xiàn)原理分析_衣舞晨風(fēng)-CSDN博客_jdk動(dòng)態(tài)代理
10.ThreadLocal
ThreadLocal是JDK包提供的讨韭,它提供線(xiàn)程本地變量脂信,在實(shí)際多線(xiàn)程操作的時(shí)候癣蟋,操作的是自己本地內(nèi)存中的變量——規(guī)避了線(xiàn)程安全問(wèn)題;
兩個(gè)本地變量inheritableThreadLocals和threadLocals狰闪,都是ThreadLocalMap類(lèi)型的變量疯搅,使用完需要 remove(),否則可能一直存在弱引用埋泵,會(huì)導(dǎo)致內(nèi)存溢出幔欧。
threadLocals不支持繼承性,同一個(gè)ThreadLocal變量在父線(xiàn)程中被設(shè)置值后丽声,在子線(xiàn)程中是獲取不到的
inheritableThreadLocals子線(xiàn)程中可獲取礁蔗,重寫(xiě)了了childValue、getMap雁社、createMap三個(gè)方法
弱引用:當(dāng)一個(gè)線(xiàn)程調(diào)用ThreadLocal的set方法設(shè)置變量的時(shí)候浴井,當(dāng)前線(xiàn)程的ThreadLocalMap就會(huì)存放一個(gè)記錄,這個(gè)記錄的key值為T(mén)hreadLocal的弱引用
key是弱引用霉撵,所以當(dāng)前線(xiàn)程的ThreadLocalMap里面的ThreadLocal變量的弱引用在gc的時(shí)候就被回收磺浙,但是對(duì)應(yīng)的value還是存在的這就可能造成內(nèi)存泄漏(因?yàn)檫@個(gè)時(shí)候ThreadLocalMap會(huì)存在key為null但是value不為null的entry項(xiàng))
remove方法判斷該當(dāng)前線(xiàn)程對(duì)應(yīng)的threadLocals變量是否為null,不為null就直接刪除當(dāng)前線(xiàn)程中指定的threadLocals變量
Java中的ThreadLocal詳解 - CoderSheeper - 博客園