日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

java面試題 --- 并發(fā)②

 貪挽懶月 2022-06-20 發(fā)布于廣東

1. JDK1.6 開(kāi)始對(duì) synchronized 做了哪些優(yōu)化?
使用了鎖升級(jí)、鎖粗化、鎖消除等方式來(lái)優(yōu)化性能。

  • 鎖升級(jí)就是先嘗試偏向鎖,如果沒(méi)獲取到鎖就升級(jí)為輕量級(jí)鎖,還沒(méi)獲取到就升級(jí)為重量級(jí)鎖;
  • 鎖粗化就是如果連續(xù)一系列的操作都對(duì)同一段代碼反復(fù)加鎖和解鎖,就將加鎖范圍擴(kuò)大,減少加解鎖的次數(shù);
  • 鎖消除就是如果某一段代碼加了鎖但是根本不會(huì)存在并發(fā)競(jìng)爭(zhēng)資源的問(wèn)題,那么虛擬機(jī)就會(huì)把鎖去掉。

2. Synchronized 和 ReentrantLock 有何異同?

  • Synchronized 是 JVM 層面的關(guān)鍵字,ReentrantLock 是 API 層面的;
  • Synchronized 可以修飾代碼塊和方法,ReentrantLock 只能用于代碼塊;
  • Synchronized 不需要手動(dòng)釋放鎖,ReentrantLock 需要手動(dòng)釋放鎖;
  • Synchronized 是非公平鎖,ReentrantLock 可以通過(guò)參數(shù)指定為公平或者非公平;
  • Synchronized 等待不能中斷,ReentrantLock 等待可以中斷,tryLock 可以設(shè)置等待時(shí)長(zhǎng);
  • Synchronized 和 ReentrantLock 都是可重入鎖。

3. volatile 有什么作用?

  • 它可以保證可見(jiàn)性,禁止指令重排,但是不能保證原子性。在 JMM 內(nèi)存模型中,線(xiàn)程操作共享資源是先將主存中的共享資源拷貝回自己的工作內(nèi)存,在工作內(nèi)存中完成修改后刷回到主存,在同步回主存之前,別的線(xiàn)程是不知道這個(gè)值已經(jīng)被改了的,這便是可見(jiàn)性問(wèn)題。用 volatile 就可以保證一個(gè)線(xiàn)程對(duì)共享資源的操作對(duì)別的線(xiàn)程可見(jiàn)。JVM 編譯代碼的時(shí)候,會(huì)對(duì)代碼做優(yōu)化,使其有更好的性能,這就是指令重排。用 volatile 可以禁止指令重排。

4. final 關(guān)鍵字有什么特性?

  • final 修飾的對(duì)象不可變,可以保證內(nèi)存的可見(jiàn)性,不需要額外的同步手段。

5. 說(shuō)說(shuō)你對(duì) as if serial 和 happen before 的理解。

  • as if serial 就是在單線(xiàn)程的情況下,不管怎么指令重排,運(yùn)行結(jié)果都要保持不變;
  • happen before 就是正確同步的多線(xiàn)程程序不管怎么指令重排運(yùn)行結(jié)果要保持不變。

6. ReentrantLock 的加鎖和解鎖過(guò)程是怎樣的?
加鎖過(guò)程:

  • 加鎖的時(shí)候?qū)嶋H上調(diào)用的是 NonfairSync/FairSync 的 lock 方法;
  • lock 方法首先調(diào)用 compareAndSetState(0, 1) 方法,如果當(dāng)前 state 是0,就改成1,同時(shí)調(diào)用 setExclusiveOwnerThread 方法將持有鎖線(xiàn)程設(shè)置為當(dāng)前線(xiàn)程,加鎖成功;
  • 如果當(dāng)前 state 不是0,表示鎖被別的線(xiàn)程持有,就用 acquire(1) 方法嘗試獲取鎖;
  • acquire(1) 首先會(huì)用 tryAcquire(1) 方法嘗試獲取鎖,該方法會(huì)判斷 state 的值,是0,那就進(jìn)行步驟2的操作;不是0但是當(dāng)前線(xiàn)程等于正持有鎖的線(xiàn)程,那就讓 state 加1,這就是可重入原理;不是以上兩種情況,那就嘗試獲取鎖失敗;
  • tryAcquire(1) 失敗就會(huì)調(diào)用 acquireQueued 方法將當(dāng)前線(xiàn)程加入到隊(duì)列自旋;
  • 最后會(huì)調(diào)用 LockSupport 的 park 方法獲取鎖。

釋放鎖過(guò)程:

  • 調(diào)用的實(shí)際上是 NonfairSync/FairSync 的 release 方法;
  • release 調(diào)用的又是 tryRelease(1) 方法;
  • tryRelease(1) 會(huì)將當(dāng)前 state 減1,同時(shí)把當(dāng)前持有鎖的線(xiàn)程設(shè)置為 null;
  • 最后調(diào)用 unparkSuccessor 方法,該方法里面調(diào)用 lockSupport 的 unpark 方法釋放鎖。

7. ReentrantReadWriteLock 怎么用一個(gè) state 來(lái)表示讀鎖和寫(xiě)鎖的狀態(tài)的?

  • ReentrantReadWriteLock 讀鎖是共享鎖,寫(xiě)鎖是獨(dú)占鎖,它用 AQS 中的 state 變量的高十六位來(lái)表示讀鎖,值就是持有讀鎖的線(xiàn)程數(shù)量,低十六位表示寫(xiě)鎖,值為零或者一,若是大于一,那就是重入的次數(shù)。

8. 并發(fā)的時(shí)候 List 不安全,有哪些解決辦法?

  • 加鎖;
  • 用 Vector;
  • 用 Collections.synchronizedList 方法;
  • 用 CopyOnWriteArrayList,它寫(xiě)之前會(huì)拷貝一份,寫(xiě)完再把引用指向拷貝的副本。

9. 你還用過(guò)哪些并發(fā)工具類(lèi)?

  • CountDownLatch 等待一組線(xiàn)程執(zhí)行完,主線(xiàn)程再繼續(xù)執(zhí)行;CycliBarriar 類(lèi)似,不過(guò) CountDownLatch 是減計(jì)數(shù),即倒數(shù),倒數(shù)到 0 釋放所有等待的線(xiàn)程,調(diào)用 countDown() 方法計(jì)數(shù)減一,調(diào)用 await() 方法只進(jìn)行阻塞;CycliBarriar 是加計(jì)數(shù),即順數(shù),計(jì)數(shù)到指定值時(shí)釋放等待線(xiàn)程,調(diào)用 await() 方法計(jì)數(shù)加 1,若加 1后的值不等于構(gòu)造方法的值,則線(xiàn)程阻塞;Semaphore,構(gòu)造方法傳入一個(gè) int 參數(shù),相當(dāng)于限定并發(fā)數(shù),比如傳的是 3,那么并發(fā)數(shù)只能是3。

10. 有沒(méi)有了解過(guò) ThreadLocal?

  • ThreadLocal 是用來(lái)做數(shù)據(jù)隔離的,ThreadLocal 保存的數(shù)據(jù)只對(duì)當(dāng)前線(xiàn)程可見(jiàn)。用 set 方法設(shè)置數(shù)據(jù),get 方法獲取數(shù)據(jù)。原理是 Thread 類(lèi)有個(gè) ThreadLocal.ThreadLocalMap 類(lèi)型的變量 threadLocals, ThreadLocal set 數(shù)據(jù)的時(shí)候,會(huì)判斷當(dāng)前線(xiàn)程類(lèi)的 threadLocals 是否為空,如果為空,就會(huì)創(chuàng)建一個(gè) ThreadLocalMap,然后以當(dāng)前的 ThreadLocal 為 key,把 value set 進(jìn)去, 并且讓 threadLocals 引用指向它;如果不為空,就直接拿來(lái)用。常用于保存數(shù)據(jù)庫(kù)連接,做 session、cookie 的隔離。ThreadLocal 在作為 ThreadLocalMap 的 key 時(shí)候被設(shè)計(jì)成弱引用了,但是我們 new ThreadLocal 實(shí)例的時(shí)候是強(qiáng)引用,所以 GC 此時(shí)并不會(huì)回收它,當(dāng) ThreadLocal 實(shí)例的生命周期結(jié)束了,沒(méi)有強(qiáng)引用指向它了,那么它作為 ThreadLocalMap 的 key 就只有弱引用,GC 發(fā)現(xiàn)了就會(huì)回收它,key 被回收了,那 value 永遠(yuǎn)都用不了,就存在內(nèi)存泄漏問(wèn)題,解決辦法就是用完之后主動(dòng)調(diào)用 remove 方法。

掃描二維碼

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多