日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

java面试线程必备知识点,怼死面试官,从我做起

發(fā)布時(shí)間:2023/12/3 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java面试线程必备知识点,怼死面试官,从我做起 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

轉(zhuǎn)載自?java面試線程必備知識(shí)點(diǎn),懟死面試官,從我做起

|--多線程一定好么?

cpu密集不好 io密集好

|--如何減少上下文切換:

無(wú)鎖并發(fā)(數(shù)據(jù)id根據(jù)Hash分段)、CAS、最少線程

|--java線程避免死鎖:

避免一個(gè)線程同時(shí)有多個(gè)鎖

避免一個(gè)鎖占用多個(gè)資源

lock.tryLock代替內(nèi)部鎖

內(nèi)存屏障:限制命令操作順序,有LoadLoad、LoadStore、LoadStore、StroreStreo四種屏障

緩沖行:cpu緩存最小儲(chǔ)存單位

寫命中:緩存有,直接寫入緩存

緩存一致性:主存改變,其他緩存改變(read、load、use綁定)

順序一致性:單個(gè)線程內(nèi)執(zhí)行結(jié)果一定是不變的(但依然有指令重排,只是結(jié)果不受影響的重排)

|--八個(gè)CPU原子命令:

lock、unlock、read、load、use、assign、store、write

|--volatile做的事:

1.lock前綴指令使緩存行立即寫入內(nèi)存(assign、store、write綁定)

2.其他cpu緩存無(wú)效

3.加入內(nèi)存屏障

使用前景:不依賴于上次數(shù)據(jù)

使用案例:i++:tmp = i;tmp=tmp+1;i = tmp;

64位機(jī)器跑32位jvm,long和double:2段分2次計(jì)算,不加volatile會(huì)導(dǎo)致結(jié)果前32位是一個(gè)線程結(jié)果,后32位一個(gè)線程結(jié)果

|--synchronized

對(duì)象加鎖,Monitor對(duì)象,monitorenter和monitorexit命令實(shí)現(xiàn)

鎖升級(jí)

|--ReentrantLock 可重入鎖

通過(guò)CVS等實(shí)現(xiàn),比synchronized效率略高,有公平鎖非公平鎖

鎖可多次進(jìn)入,并把擁有數(shù)++

lock(), 如果獲取了鎖立即返回,如果別的線程持有鎖,當(dāng)前線程則一直處于休眠狀態(tài),直到獲取鎖

tryLock(), 如果獲取了鎖立即返回true,如果別的線程正持有鎖,立即返回false;

|--ReentrantReadWriteLock

read/write兩把鎖

寫鎖與ReetrantLock類似,只有寫鎖讀鎖都沒(méi)被占用才獲得鎖

讀鎖擁有數(shù)是多個(gè)線程的,每個(gè)線程擁有數(shù)只能自己通過(guò)ThreadLocal記錄

寫鎖結(jié)束降級(jí)讀鎖,避免可見(jiàn)性問(wèn)題

|--Lock和synchronized區(qū)別

Lock是通過(guò)代碼級(jí)實(shí)現(xiàn),cvs

synchronized是通過(guò)jvm的monitor實(shí)現(xiàn)的

還多了 鎖投票,定時(shí)鎖等候和中斷鎖等候等特性

使用ReentrantLock,如果A不釋放,可以使B在等待了足夠長(zhǎng)的時(shí)間以后,中斷等待,而干別的事情

|--AQS(AbstractQueuedSynchronized)

有隊(duì)列,有state、進(jìn)入會(huì)先自旋再阻塞,默認(rèn)非公平,隊(duì)列喚醒了調(diào)用tryAcquire,不一定能獲取鎖

|--java對(duì)象頭:

MarkWord 長(zhǎng)度:32/64,存儲(chǔ)hashCode或者鎖信息

|--CAS unsafe.compareAndSwap(對(duì)象地址,原來(lái)值,要修改值)

unsafe是通過(guò)操作系統(tǒng)實(shí)現(xiàn)(CMPXCHG指令),如果失敗返回false;

|--CAS使用:自旋鎖、自適應(yīng)自旋鎖

|--鎖的升級(jí)

偏向鎖(markword指向所在線程,代價(jià)低,兩個(gè)線程則停安全點(diǎn)撤銷)->輕量級(jí)線程(markword置換到擁有者線程,線程對(duì)象互指。兩個(gè)線程則b線程自旋等待)->重量級(jí)鎖(syn、reeentrantLock)

比較:

偏向鎖: ?加鎖解鎖消耗極少,鎖競(jìng)爭(zhēng)的安全點(diǎn)帶來(lái)消耗。 ? ? ?適用于一個(gè)線程

輕量級(jí)鎖:響應(yīng)快,自旋消耗cpu ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?追求響應(yīng)時(shí)間,同步塊非常快

重量級(jí): ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?追求吞吐量,同步塊執(zhí)行時(shí)間長(zhǎng)

|--處理器實(shí)現(xiàn)原子性策略:

LOCK#信號(hào)是一個(gè)線程獨(dú)占共享內(nèi)存(通過(guò)鎖住主內(nèi)存總線,之后優(yōu)化成緩存鎖)

緩存鎖保證原子性

|--java原子實(shí)現(xiàn):

鎖和CAS

CAS局限性:ABA問(wèn)題(過(guò)程無(wú)感知)、循環(huán)時(shí)間開(kāi)銷大、一次保證一個(gè)變量

|--內(nèi)存模型(對(duì)底層抽象)

線程通信方式:

內(nèi)存模型(共享內(nèi)存)

消息傳遞(A復(fù)制到主內(nèi)存,再?gòu)闹鲀?nèi)存寫到B)

管道:輸入流輸出流(PipedReader,PipedWriter,PipedInputstream,PipedOutputStream)

內(nèi)存模型:本地內(nèi)存(共享變量副本、局部變量)、主內(nèi)存(共享變量)

指令重排序:編譯優(yōu)化重排、并行重排、內(nèi)存重排

|--final域重寫規(guī)則

構(gòu)造函數(shù)內(nèi),final寫入與被構(gòu)造的對(duì)象引用賦值不能重排序(obj=this會(huì)引發(fā)逃逸,例如此時(shí)別的線程調(diào)用obj.i,final的i變量還沒(méi)初始化)

初次讀含final域?qū)ο笈c隨后讀final區(qū)域不能重排

|--單例模式問(wèn)題

實(shí)例化分為:1.開(kāi)辟空間memory 2.初始化對(duì)象 3.設(shè)置instance指向memory。

指令重排可能是:1->3->2 , 若2還未執(zhí)行,B線程認(rèn)為instance非空,直接調(diào)用instance,導(dǎo)致錯(cuò)誤

解決方案:1.volatile禁止重排序 2.匿名內(nèi)部類(連自己加鎖都不用,類自帶實(shí)例化鎖)

|--為什么使用多線程

1.多處理器發(fā)揮功效

2.更快相應(yīng),一個(gè)下訂單帶來(lái)一系列操作如何快速成功:線程派發(fā),分任務(wù)執(zhí)行

|--java優(yōu)先級(jí)

不一定有用,主要是靠操作系統(tǒng)底層實(shí)現(xiàn)

|--interrupt

interrupt不會(huì)真的終止,只是一種協(xié)作機(jī)制

interrupt()將會(huì)設(shè)置該線程的中斷狀態(tài)位,即設(shè)置為true

使用Thread.currentThread().isInterrupted()方法(因?yàn)樗鼘⒕€程中斷標(biāo)示位設(shè)置為true后,不會(huì)立刻清除中斷標(biāo)示位,即不會(huì)將中斷標(biāo)設(shè)置為false)

thread.interrupted()(該方法調(diào)用后會(huì)將中斷標(biāo)示位清除,即重新設(shè)置為false)

一個(gè)線程處于了等待狀態(tài)(thread.sleep、thread.join、thread.wait),則在線程在檢查中斷標(biāo)示時(shí)如果發(fā)現(xiàn)中斷標(biāo)示為true,則會(huì)在這些阻塞方法調(diào)用處拋出InterruptedException異常,并且在拋出異常后立即將線程的中斷標(biāo)示位清除,即重新設(shè)置為false。拋出異常是為了線程從阻塞狀態(tài)醒過(guò)來(lái),并在結(jié)束線程前讓程序員有足夠的時(shí)間來(lái)處理中斷請(qǐng)求。

鎖的情況下不會(huì)被中斷影響

|--阻塞狀態(tài)與等待區(qū)別

阻塞是進(jìn)鎖里,等待是wait、sleep。sleep設(shè)置時(shí)間狀態(tài)叫做超時(shí)等待狀態(tài)

|--線程的應(yīng)用

1.等待之后超時(shí)

while(結(jié)果未返回 && 時(shí)間未到)

wait();

2.線程池

要有隊(duì)列,狀態(tài)

Worker實(shí)現(xiàn)Runnable接口,循環(huán)從jobs隊(duì)列取任務(wù)執(zhí)行,獲取不到就wait();

execute(Job job)時(shí),喚醒jobs

3.基于線程池Web服務(wù)器

思路:開(kāi)一個(gè)Socket服務(wù),每次accept后,把這個(gè)一對(duì)一服務(wù)放封裝成job類,放到j(luò)obs隊(duì)列里

|--LockSupport

工具類,有park、unpark阻塞喚醒線程

|--Condition

相當(dāng)于Lock中的wait和notify,區(qū)別是wait等待隊(duì)列只能有一個(gè),Condition可以有多個(gè)

Condition隊(duì)列類似于AQS隊(duì)列

每個(gè)Condition下面有一個(gè)等待await的等待隊(duì)列

Lock.newCondition()獲取condition

Lock.await(); = wait

Lock.singal();=notify

|--ConcurrentHashMap

問(wèn)題:HashMap線程不安全導(dǎo)致Entry鏈表編程環(huán),引發(fā)死循環(huán)。

HashTable效率低

解決:Segment包含HashEntry數(shù)組

Segment是一種可重入鎖(ReentrantLock)

實(shí)現(xiàn):segment數(shù)量是2的n次方,默認(rèn)16

每一個(gè)segment的容量=每個(gè)segment里HashEntry*負(fù)載因子

如何放入數(shù)據(jù):再散列確保數(shù)據(jù)分散后放入segment

get方法:不加鎖,而是用volatile

1.8更新:沒(méi)有了segment,橫向用Node鏈表替代,Node被調(diào)用取時(shí)就synchronize加鎖。當(dāng)沒(méi)Node底下鏈表超過(guò)8個(gè),將加鎖

|--ConcurrentLinkedQueue

非阻塞

入隊(duì):定位尾節(jié)點(diǎn),不成功cvs重試(為了減少CVS,控制尾節(jié)點(diǎn)更新頻率)

出隊(duì):

總結(jié)

以上是生活随笔為你收集整理的java面试线程必备知识点,怼死面试官,从我做起的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。