并發(fā)進(jìn)階常面題

說一說自己對(duì)于 synchronized 關(guān)鍵字的了解

synchronized關(guān)鍵字解決多個(gè)線程之間訪問資源的同步性,被synchronized關(guān)鍵字能保證被他修飾的方法和代碼塊在任意時(shí)刻都只有一個(gè)線程訪問

說說自己是怎么使用 synchronized 關(guān)鍵字,在項(xiàng)目中用到了嗎

synchronized關(guān)鍵字主要用于三種場(chǎng)景:①修飾實(shí)例方法:也就是給當(dāng)前實(shí)例對(duì)象加鎖,當(dāng)進(jìn)入到同步代碼塊之前需要獲得當(dāng)前對(duì)象的鎖②修飾靜態(tài)方法:也就是給當(dāng)前類加鎖,作用于改類的所有實(shí)例對(duì)象,而靜態(tài)資源是不屬于實(shí)例對(duì)象的,是屬于類的。所以如果有一個(gè)線程訪問synchronized修飾的非靜態(tài)方法,另一個(gè)線程訪問synchronize修飾的靜態(tài)方法,是不會(huì)出現(xiàn)互斥的。因?yàn)閟ynchronized修飾的非靜態(tài)方法是當(dāng)前實(shí)例對(duì)象的鎖,而synchronize修飾的靜態(tài)方法是類的鎖。③修飾代碼塊:也就是給給定對(duì)象加鎖,在訪問同步代碼塊之前需要獲得給定對(duì)象的鎖

什么是雙重檢查鎖實(shí)現(xiàn)單例?代碼是什么樣子的?

雙重檢查鎖實(shí)現(xiàn)單例就是在創(chuàng)建單例對(duì)象的時(shí)候會(huì)進(jìn)行兩次判斷實(shí)例是否存在,一次加鎖判斷一次不加鎖判斷

代碼:

說說 JDK1.6 之后的synchronized 關(guān)鍵字底層做了哪些優(yōu)化,可以詳細(xì)介紹一下這些優(yōu)化嗎

JDK1.6版本之后,對(duì)鎖的做了很多優(yōu)化,比如說:偏向鎖,自旋鎖,輕量級(jí)鎖,鎖粗化等技術(shù)來減少鎖操作的開銷。鎖的狀態(tài)有四種,分別是:無鎖狀態(tài),偏向鎖狀態(tài),輕量級(jí)鎖狀態(tài)和重量級(jí)鎖狀態(tài),他們會(huì)隨著競(jìng)爭(zhēng)的激烈而提升,鎖是可以提升但不可以降級(jí),這種策略是為了提高獲得鎖和釋放鎖的效率。

談?wù)?synchronized和ReentrantLock 的區(qū)別

相同:他們都是可重入鎖

區(qū)別:①synchronized在競(jìng)爭(zhēng)鎖的時(shí)候會(huì)一直等待,ReentrantLock會(huì)嘗試去獲取鎖,并將獲取結(jié)果返回

②synchronized獲取鎖的時(shí)候不能設(shè)置超時(shí)時(shí)間,ReentrantLock可以設(shè)置超時(shí)時(shí)間

③synchronized不能滿足公平鎖,而ReentrantLock可以滿足公平鎖

④synchronized是依賴于JVM的,而ReentrantLock是依賴于JDK的API

⑤synchronized在執(zhí)行鎖代碼塊的時(shí)候出現(xiàn)異常會(huì)自動(dòng)釋放鎖,而ReentrantLock不會(huì),他需要在finally{}中釋放鎖


并發(fā)編程的三大特征以及volatile關(guān)鍵字的作用?

并發(fā)編程有三大特性,分別是:①原子性:一個(gè)操作或多次操作在執(zhí)行過程中要么全部執(zhí)行完成,要么全部不執(zhí)行②可見性:當(dāng)一個(gè)變量對(duì)共享變量進(jìn)行修改值時(shí),其他線程也可以同時(shí)第一時(shí)間獲得變量修改之后的值③有序性:代碼執(zhí)行過程中是有序的

volatile關(guān)鍵字可以保證可變變量的可見性以及防止指令重排序

說說 synchronized 關(guān)鍵字和 volatile 關(guān)鍵字的區(qū)別

synchronized關(guān)鍵字和volatile關(guān)鍵字的作用是互補(bǔ)的

①volatile關(guān)鍵字是線程同步的輕量級(jí)實(shí)現(xiàn),所以他的性能比synchronized的性能要高,但是volatile關(guān)鍵字只能修飾變量,而synchronized關(guān)鍵字可以修飾方法和代碼塊,所以我們使用synchronized關(guān)鍵字的場(chǎng)景比較多。②多線程訪問volatile關(guān)鍵字不會(huì)發(fā)生線程堵塞,但是訪問synchronize關(guān)鍵字可能會(huì)發(fā)生堵塞③volatile關(guān)鍵字能保證數(shù)據(jù)的可見性,但不能保證數(shù)據(jù)的原子性,而synchronized關(guān)鍵字兩者都能保證④volatile關(guān)鍵字主要解決于多線程之間的變量可見性,而synchronized關(guān)鍵字主要是解決多線程之間的訪問資源的同步性


ThreadLocal有什么作用?有哪些使用場(chǎng)景?

ThreadLocal是線程本地存儲(chǔ)。每個(gè)線程都創(chuàng)建一個(gè)ThreadLocalMap對(duì)象,然后每個(gè)線程都可以訪問自己的ThreadLocalMap對(duì)象中的value。通過這種方法,可以避免資源在多線程之間的共享。

常用的使用場(chǎng)景是給每一個(gè)線程分配一個(gè)JDBC的連接對(duì)象,這樣子就可以保證


什么是線程池?

線程池就是創(chuàng)建若干個(gè)線程存放到一個(gè)池里面,當(dāng)有任務(wù)需要處理的時(shí)候,就到線程池中 的任務(wù)隊(duì)列中,等任務(wù)執(zhí)行完成之后,線程不會(huì)被銷毀,而是回到線程池中等待下一個(gè)任務(wù)。

線程池的優(yōu)點(diǎn)

線程池的特點(diǎn)是:線程可復(fù)用? 可設(shè)置最大并發(fā)量? ? 可管理線程

線程池的優(yōu)點(diǎn)是:降低資源消耗? 提高響應(yīng)效率? ? 提高線程的可管理性


實(shí)現(xiàn)Runnable接口和Callable接口的區(qū)別

①Runnable的run()方法只能拋出運(yùn)行時(shí)異常,并且不能處理,而Callable的call()方法可以捕捉異常,并且返回異常信息②Runnable的run()方法沒有返回值,Callable的call()方法有返回值,并且支持泛型


執(zhí)行execute()方法和submit()方法的區(qū)別是什么呢?

execute()方法用于提交不需要返回值的任務(wù),任務(wù)提交之后我們沒法判斷任務(wù)是否在線程池中成功完成submit()方法用于提交需要返回值的任務(wù),線程池會(huì)返回一個(gè)Future對(duì)象,我們可以通過Future對(duì)象判斷任務(wù)是否成功完成,并且可以跳過Futrue中的get()方法獲取到返回值


如何創(chuàng)建線程池?

我們可以通過兩種方式來創(chuàng)建線程池:

第一種是通過構(gòu)造器來實(shí)現(xiàn),也就是ThreadPoolExecutor

第二種是通過Executor的工具類Executors來實(shí)現(xiàn),我們可以創(chuàng)建三種線程池
FixedThreadPool:創(chuàng)建返回指定線程數(shù)量的線程池
SingleThreadExecutor:創(chuàng)建只返回一個(gè)線程對(duì)象的線程池
CacheThreadPool:創(chuàng)建可以根據(jù)實(shí)際情況創(chuàng)建線程數(shù)量的線程池


線程池的原理分析(執(zhí)行流程)

當(dāng)一個(gè)任務(wù)提交的時(shí)候回到線程池中判斷核心線程數(shù)數(shù)量是否已經(jīng)達(dá)到最大,如果不是的話就會(huì)創(chuàng)建一個(gè)線程,如果是的話就到任務(wù)隊(duì)列中看是否已滿,如果沒滿的話就會(huì)到任務(wù)隊(duì)列中排隊(duì),如果滿了的話就判斷線程池的最大線程數(shù)是否已達(dá)到最大,如果沒有則創(chuàng)建線程,如果已經(jīng)達(dá)到最大的話就會(huì)執(zhí)行RejectedExecutionHandle方法拒絕此次任務(wù)提交


介紹一下Atomic 原子類

Atomic就是原子類,在這里的意思是一旦操作執(zhí)行就不會(huì)被打斷,就算多個(gè)線程同時(shí)在執(zhí)行,操作一旦開始,不會(huì)受其他線程的影響。它具有原子性的特征


什么是JUC

JUC是java.util.concurrent包的簡(jiǎn)稱,他是一個(gè)工具包,里面包含了很多原子類,這些原子類可以更好的提高線程的高并發(fā),已經(jīng)避免多線程執(zhí)行過程中出現(xiàn)死鎖的情況


JUC 包中的原子類是哪4類?

JUC包中包括四種原子性類,分別是:整形原子型,數(shù)組類型原子型,引用類型原子型,基于對(duì)象類型修改原子型

整形原子型的類有:AtomicIntegerAtomicLongAtomicBoolean數(shù)組類型原子型:AtomicIntegerArrayAtomicLongArrayAtomicReferenceArray引用類型原子型:AtomicReferenceAtomicStamtedReferenceAtomicMarkableReference基于對(duì)象類型修改原子型:AtomicStmtedReferenceAtomicIntegerFieldUpdater AtomicLongFieldUpdater?


講講 AtomicInteger 的使用

AtomicInteger中有很多方法,比如getAndSet() , getAndIncrement() , getAndAdd()等方法,而我們使用的時(shí)候就創(chuàng)建一個(gè)AtomicInteger對(duì)象,然后調(diào)用對(duì)應(yīng)的方法,再將調(diào)用方法后得出的結(jié)果賦值給一個(gè)int類型變量

能不能給我簡(jiǎn)單介紹一下 AtomicInteger 類的原理

AtomicInteger類是Atomic原子類中的整形原子類中的一個(gè)類,他是通過CAS(compare and swap)和volatile以及native方法來保證原子性操作,從而減少synchronize關(guān)鍵字的開銷,提高執(zhí)行效率


AQS 原理概覽

AQS的基本原理就是:當(dāng)一個(gè)請(qǐng)求進(jìn)入到共享資源的時(shí)候,會(huì)判斷這個(gè)共享資源是否為空閑,如果是的話就將當(dāng)前這個(gè)線程設(shè)置成有效工作線程,并且將共享資源給鎖住;如果不是的話,就會(huì)進(jìn)入線程阻塞等待以及喚醒的時(shí)候分配鎖的一個(gè)機(jī)制,這個(gè)機(jī)制是由CLH的隊(duì)列鎖實(shí)現(xiàn)的,如果暫時(shí)沒有分配到鎖的線程就會(huì)進(jìn)入到隊(duì)列中


shutdown() VS shutdownNow()

shutdown():關(guān)閉線程池,不再接受新的任務(wù),但是回將隊(duì)列里的任務(wù)執(zhí)行完畢shutdownNow():關(guān)閉線程池,停止當(dāng)前正在執(zhí)行的任務(wù),并且將隊(duì)列中的任務(wù)停止處理,并將正在排隊(duì)的返回一個(gè)List

常用的線程池

FixedThreadPool

SecheduledThreadPoolExecutor

CachedThreadPool

SingleThreadExecutor

什么是悲觀鎖和樂觀鎖

樂觀鎖:他總是很樂觀,覺得不會(huì)發(fā)生并發(fā)問題,在他讀取數(shù)據(jù)的時(shí)候覺得不會(huì)有其他線程來修改數(shù)據(jù),所以不加鎖,但是在修改數(shù)據(jù)的時(shí)候他會(huì)去判斷在此之前是否有其他線程對(duì)數(shù)據(jù)進(jìn)行修改,通常是使用CAS和版本號(hào)機(jī)制來操作

悲觀鎖:他總是很悲觀,他覺得在數(shù)據(jù)讀取的時(shí)候會(huì)有其他線程來修改數(shù)據(jù),所以他總是加鎖,如果其他線程要獲取該數(shù)據(jù)的話,會(huì)出現(xiàn)阻塞狀態(tài),然后等到鎖的時(shí)候再讀取數(shù)據(jù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容