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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

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

轉載自?java面試線程必備知識點,懟死面試官,從我做起

|--多線程一定好么?

cpu密集不好 io密集好

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

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

|--java線程避免死鎖:

避免一個線程同時有多個鎖

避免一個鎖占用多個資源

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

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

緩沖行:cpu緩存最小儲存單位

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

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

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

|--八個CPU原子命令:

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

|--volatile做的事:

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

2.其他cpu緩存無效

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

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

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

64位機器跑32位jvm,long和double:2段分2次計算,不加volatile會導致結果前32位是一個線程結果,后32位一個線程結果

|--synchronized

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

鎖升級

|--ReentrantLock 可重入鎖

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

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

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

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

|--ReentrantReadWriteLock

read/write兩把鎖

寫鎖與ReetrantLock類似,只有寫鎖讀鎖都沒被占用才獲得鎖

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

寫鎖結束降級讀鎖,避免可見性問題

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

Lock是通過代碼級實現(xiàn),cvs

synchronized是通過jvm的monitor實現(xiàn)的

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

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

|--AQS(AbstractQueuedSynchronized)

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

|--java對象頭:

MarkWord 長度:32/64,存儲hashCode或者鎖信息

|--CAS unsafe.compareAndSwap(對象地址,原來值,要修改值)

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

|--CAS使用:自旋鎖、自適應自旋鎖

|--鎖的升級

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

比較:

偏向鎖: ?加鎖解鎖消耗極少,鎖競爭的安全點帶來消耗。 ? ? ?適用于一個線程

輕量級鎖:響應快,自旋消耗cpu ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?追求響應時間,同步塊非常快

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

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

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

緩存鎖保證原子性

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

鎖和CAS

CAS局限性:ABA問題(過程無感知)、循環(huán)時間開銷大、一次保證一個變量

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

線程通信方式:

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

消息傳遞(A復制到主內(nèi)存,再從主內(nèi)存寫到B)

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

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

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

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

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

初次讀含final域對象與隨后讀final區(qū)域不能重排

|--單例模式問題

實例化分為:1.開辟空間memory 2.初始化對象 3.設置instance指向memory。

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

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

|--為什么使用多線程

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

2.更快相應,一個下訂單帶來一系列操作如何快速成功:線程派發(fā),分任務執(zhí)行

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

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

|--interrupt

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

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

使用Thread.currentThread().isInterrupted()方法(因為它將線程中斷標示位設置為true后,不會立刻清除中斷標示位,即不會將中斷標設置為false)

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

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

鎖的情況下不會被中斷影響

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

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

|--線程的應用

1.等待之后超時

while(結果未返回 && 時間未到)

wait();

2.線程池

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

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

execute(Job job)時,喚醒jobs

3.基于線程池Web服務器

思路:開一個Socket服務,每次accept后,把這個一對一服務放封裝成job類,放到jobs隊列里

|--LockSupport

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

|--Condition

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

Condition隊列類似于AQS隊列

每個Condition下面有一個等待await的等待隊列

Lock.newCondition()獲取condition

Lock.await(); = wait

Lock.singal();=notify

|--ConcurrentHashMap

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

HashTable效率低

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

Segment是一種可重入鎖(ReentrantLock)

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

每一個segment的容量=每個segment里HashEntry*負載因子

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

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

1.8更新:沒有了segment,橫向用Node鏈表替代,Node被調(diào)用取時就synchronize加鎖。當沒Node底下鏈表超過8個,將加鎖

|--ConcurrentLinkedQueue

非阻塞

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

出隊:

總結

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

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