日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
肝了一夜的66道并發(fā)多線程面試題,你不來(lái)個(gè)666嗎?

 大家好,我是狼王,一個(gè)愛(ài)打球的程序員

創(chuàng)新互聯(lián)一直通過(guò)網(wǎng)站建設(shè)和網(wǎng)站營(yíng)銷(xiāo)幫助企業(yè)獲得更多客戶資源。 以"深度挖掘,量身打造,注重實(shí)效"的一站式服務(wù),以網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站設(shè)計(jì)、移動(dòng)互聯(lián)產(chǎn)品、成都全網(wǎng)營(yíng)銷(xiāo)推廣服務(wù)為核心業(yè)務(wù)。10年網(wǎng)站制作的經(jīng)驗(yàn),使用新網(wǎng)站建設(shè)技術(shù),全新開(kāi)發(fā)出的標(biāo)準(zhǔn)網(wǎng)站,不但價(jià)格便宜而且實(shí)用、靈活,特別適合中小公司網(wǎng)站制作。網(wǎng)站管理系統(tǒng)簡(jiǎn)單易用,維護(hù)方便,您可以完全操作網(wǎng)站資料,是中小公司快速網(wǎng)站建設(shè)的選擇。

我花了點(diǎn)時(shí)間整理了一些多線程,并發(fā)相關(guān)的面試題,雖然不是很多,但是偶爾看看還是很有用的哦!

話不多說(shuō),直接開(kāi)整!

01 什么是線程?

線程是操作系統(tǒng)能夠進(jìn)?運(yùn)算調(diào)度的最?單位,它被包含在進(jìn)程之中,是進(jìn)程中的實(shí)際運(yùn)作單位,可以使?多線程對(duì)進(jìn)?運(yùn)算提速。

02 什么是線程安全和線程不安全?

線程安全:

就是多線程訪問(wèn)時(shí),采?了加鎖機(jī)制,當(dāng)?個(gè)線程訪問(wèn)該類(lèi)的某個(gè)數(shù)據(jù)時(shí),進(jìn)?保護(hù),其他線程不能進(jìn)?訪問(wèn),直到該線程讀取完,其他線程才可使?。不會(huì)出現(xiàn)數(shù)據(jù)不?致或者數(shù)據(jù)污染。Vector 是?同步?法來(lái)實(shí)現(xiàn)線程安全的, ?和它相似的ArrayList不是線程安全的。

線程不安全:

就是不提供數(shù)據(jù)訪問(wèn)保護(hù),有可能出現(xiàn)多個(gè)線程先后更改數(shù)據(jù)造成所得到的數(shù)據(jù)是臟數(shù)據(jù) 線程安全問(wèn)題都是由全局變量及靜態(tài)變量引起的。若每個(gè)線程中對(duì)全局變量、靜態(tài)變量只有讀操作,??寫(xiě)操作,?般來(lái)說(shuō),這個(gè)全局變量是線程安全的;若有多個(gè)線程同時(shí)執(zhí)?寫(xiě)操作,?般都需要考慮線程同步,否則的話就可能影響線程安全。

03 什么是自旋鎖?

自旋鎖是SMP架構(gòu)中的?種low-level的同步機(jī)制。

當(dāng)線程A想要獲取?把自旋鎖?該鎖?被其它線程鎖持有時(shí),線程A會(huì)在?個(gè)循環(huán)中自旋以檢測(cè)鎖是不是已經(jīng)可?了。

自旋鎖需要注意:

  1. 由于自旋時(shí)不釋放CPU,因?持有自旋鎖的線程應(yīng)該盡快釋放自旋鎖,否則等待該自旋鎖的線程會(huì)?直在那?自旋,這就會(huì)浪費(fèi)CPU時(shí)間。
  2. 持有自旋鎖的線程在sleep之前應(yīng)該釋放自旋鎖以便其它線程可以獲得自旋鎖。

?前的JVM實(shí)現(xiàn)自旋會(huì)消耗CPU,如果?時(shí)間不調(diào)?doNotify?法,doWait?發(fā)會(huì)?直自旋,CPU會(huì)消耗太?。

自旋鎖?較適?于鎖使?者保持鎖時(shí)間?較短的情況,這種情況自旋鎖的效率?較?。

自旋鎖是?種對(duì)多處理器相當(dāng)有效的機(jī)制,?在單處理器?搶占式的系統(tǒng)中基本上沒(méi)有做?。

04 什么是CAS?

  1. CAS(compare and swap)的縮寫(xiě),中?翻譯成?較并交換。
  2. CAS 不通過(guò)JVM,直接利?java本地? JNI(Java Native Interface為JAVA本地調(diào)?),直接調(diào)?CPU 的cmpxchg(是匯編指令)指令。
  3. 利?CPU的CAS指令,同時(shí)借助JNI來(lái)完成Java的?阻塞算法,實(shí)現(xiàn)原?操作。其它原?操作都是利?類(lèi)似的特性完成的。
  4. 整個(gè)java.util.concurrent都是建?在CAS之上的,因此對(duì)于synchronized阻塞算法,J.U.C在性能上有了很?的提升。
  5. CAS是項(xiàng)樂(lè)觀鎖技術(shù),當(dāng)多個(gè)線程嘗試使?CAS同時(shí)更新同?個(gè)變量時(shí),只有其中?個(gè)線程能更新變量的值,?其它線程都失敗,失敗的線程并不會(huì)被掛起,?是被告知這次競(jìng)爭(zhēng)中失敗,并可以再次嘗試。
  • 使?CAS在線程沖突嚴(yán)重時(shí),會(huì)?幅降低程序性能;CAS只適合于線程沖突較少的情況使?。
  • synchronized在jdk1.6之后,已經(jīng)改進(jìn)優(yōu)化。synchronized的底層實(shí)現(xiàn)主要依靠Lock-Free的隊(duì)列,基本思路是自旋后阻塞,競(jìng)爭(zhēng)切換后繼續(xù)競(jìng)爭(zhēng)鎖,稍微犧牲了公平性,但獲得了?吞吐量。在線程沖突較少的情況下,可以獲得和CAS類(lèi)似的性能;?線程沖突嚴(yán)重的情況下,性能遠(yuǎn)?于CAS。

05 什么是樂(lè)觀鎖和悲觀鎖?

1.悲觀鎖

Java在JDK1.5之前都是靠synchronized關(guān)鍵字保證同步的,這種通過(guò)使??致的鎖定協(xié)議來(lái)協(xié)調(diào)對(duì)共享狀態(tài)的訪問(wèn),可以確保?論哪個(gè)線程持有共享變量的鎖,都采?獨(dú)占的?式來(lái)訪問(wèn)這些變量。獨(dú)占鎖其實(shí)就是?種悲觀鎖,所以可以說(shuō)synchronized是悲觀鎖。

2.樂(lè)觀鎖

樂(lè)觀鎖( Optimistic Locking)其實(shí)是?種思想。相對(duì)悲觀鎖??,樂(lè)觀鎖假設(shè)認(rèn)為數(shù)據(jù)?般情況下不會(huì)造成沖突,所以在數(shù)據(jù)進(jìn)?提交更新的時(shí)候,才會(huì)正式對(duì)數(shù)據(jù)的沖突與否進(jìn)?檢測(cè),如果發(fā)現(xiàn)沖突了,則讓返回?戶錯(cuò)誤的信息,讓?戶決定如何去做。memcached使?了cas樂(lè)觀鎖技術(shù)保證數(shù)據(jù)?致性。

06 什么是AQS?

1、AbstractQueuedSynchronizer簡(jiǎn)稱AQS,是?個(gè)?于構(gòu)建鎖和同步容器的框架。事實(shí)上concurrent包內(nèi)許多類(lèi)都是基于AQS構(gòu)建,例如ReentrantLock,Semaphore,CountDownLatch,ReentrantReadWriteLock,F(xiàn)utureTask等。AQS解決了在實(shí)現(xiàn)同步容器時(shí)設(shè)計(jì)的?量細(xì)節(jié)問(wèn)題。

2、AQS使??個(gè)FIFO的隊(duì)列表示排隊(duì)等待鎖的線程,隊(duì)列頭節(jié)點(diǎn)稱作“哨兵節(jié)點(diǎn)”或者“啞節(jié)點(diǎn)”,它不與任何線程關(guān)聯(lián)。其他的節(jié)點(diǎn)與等待線程關(guān)聯(lián),每個(gè)節(jié)點(diǎn)維護(hù)?個(gè)等待狀態(tài)waitStatus。

07 什么是原?操作?在Java Concurrency API中有哪些原?類(lèi)(atomic classes)?

  1. 原?操作是指?個(gè)不受其他操作影響的操作任務(wù)單元。原?操作是在多線程環(huán)境下避免數(shù)據(jù)不?致必須的?段。
  2. int++并不是?個(gè)原?操作,所以當(dāng)?個(gè)線程讀取它的值并加1時(shí),另外?個(gè)線程有可能會(huì)讀到之前的值,這就會(huì)引發(fā)錯(cuò)誤。
  3. 為了解決這個(gè)問(wèn)題,必須保證增加操作是原?的,在JDK1.5之前我們可以使?同步技術(shù)來(lái)做到這?點(diǎn)。

到JDK1.5,java.util.concurrent.atomic包提供了int和long類(lèi)型的裝類(lèi),它們可以自動(dòng)的保證對(duì)于他們的操作是原?的并且不需要使?同步。

08 什么是Executors框架?

Java通過(guò)Executors提供四種線程池,分別為:

newCachedThreadPool創(chuàng)建?個(gè)可緩存線程池,如果線程池?度超過(guò)處理需要,可靈活回收空閑線程,若?可回收,則新建線程。newFixedThreadPool 創(chuàng)建?個(gè)定?線程池,可控制線程最?并發(fā)數(shù),超出的線程會(huì)在隊(duì)列中等待。newScheduledThreadPool 創(chuàng)建?個(gè)定?線程池,?持定時(shí)及周期性任務(wù)執(zhí)?。newSingleThreadExecutor 創(chuàng)建?個(gè)單線程化的線程池,它只會(huì)?唯?的?作線程來(lái)執(zhí)?任務(wù),保證所有任務(wù)按照指定順序(FIFO, LIFO, 優(yōu)先級(jí))執(zhí)?。

09 什么是阻塞隊(duì)列?如何使?阻塞隊(duì)列來(lái)實(shí)現(xiàn)?產(chǎn)者-消費(fèi)者模型?

1、JDK7提供了7個(gè)阻塞隊(duì)列。(也屬于并發(fā)容器)

ArrayBlockingQueue :?個(gè)由數(shù)組結(jié)構(gòu)組成的有界阻塞隊(duì)列。LinkedBlockingQueue :?個(gè)由鏈表結(jié)構(gòu)組成的有界阻塞隊(duì)列。PriorityBlockingQueue :?個(gè)?持優(yōu)先級(jí)排序的?界阻塞隊(duì)列。DelayQueue:?個(gè)使?優(yōu)先級(jí)隊(duì)列實(shí)現(xiàn)的?界阻塞隊(duì)列。SynchronousQueue:?個(gè)不存儲(chǔ)元素的阻塞隊(duì)列。LinkedTransferQueue:?個(gè)由鏈表結(jié)構(gòu)組成的?界阻塞隊(duì)列。LinkedBlockingDeque:?個(gè)由鏈表結(jié)構(gòu)組成的雙向阻塞隊(duì)列。

2、概念:阻塞隊(duì)列是?個(gè)在隊(duì)列基礎(chǔ)上??持了兩個(gè)附加操作的隊(duì)列。

3、2個(gè)附加操作:

3.1. ?持阻塞的插??法:隊(duì)列滿時(shí),隊(duì)列會(huì)阻塞插?元素的線程,直到隊(duì)列不滿。

3.2 ?持阻塞的移除?法:隊(duì)列空時(shí),獲取元素的線程會(huì)等待隊(duì)列變?yōu)?空。

10 什么是Callable和Future?

1、Callable 和 Future 是?較有趣的?對(duì)組合。當(dāng)我們需要獲取線程的執(zhí)?結(jié)果時(shí),就需要?到它們。Callable?于產(chǎn)?結(jié)果,F(xiàn)uture?于獲取結(jié)果。

2、Callable接?使?泛型去定義它的返回類(lèi)型。Executors類(lèi)提供了?些有?的?法去在線程池中執(zhí)?Callable內(nèi)的任務(wù)。由于Callable任務(wù)是并?的,必須等待它返回的結(jié)果。java.util.concurrent.Future對(duì)象解決了這個(gè)問(wèn)題。

3、在線程池提交Callable任務(wù)后返回了?個(gè)Future對(duì)象,使?它可以知道Callable任務(wù)的狀態(tài)和得到Callable返回的執(zhí)?結(jié)果。Future提供了get()?法,等待Callable結(jié)束并獲取它的執(zhí)?結(jié)果。

11 什么是FutureTask?

1、FutureTask可?于異步獲取執(zhí)?結(jié)果或取消執(zhí)?任務(wù)的場(chǎng)景。通過(guò)傳?Runnable或者Callable的任務(wù)給FutureTask,直接調(diào)?其run?法或者放?線程池執(zhí)?,之后可以在外部通過(guò)FutureTask的get?法異步獲取執(zhí)?結(jié)果,因此,F(xiàn)utureTask?常適合?于耗時(shí)的計(jì)算,主線程可以在完成自?的任務(wù)后,再去獲取結(jié)果。另外,F(xiàn)utureTask還可以確保即使調(diào)?了多次run?法,它都只會(huì)執(zhí)??次Runnable或者Callable任務(wù),或者通過(guò)cancel取消FutureTask的執(zhí)?等。

2、futuretask可?于執(zhí)?多任務(wù)、以及避免?并發(fā)情況下多次創(chuàng)建數(shù)據(jù)機(jī)鎖的出現(xiàn)。

12 什么是同步容器和并發(fā)容器的實(shí)現(xiàn)?

同步容器:

1、主要代表有Vector和Hashtable,以及Collections.synchronizedXxx等。

2、鎖的粒度為當(dāng)前對(duì)象整體。

3、迭代器是及時(shí)失敗的,即在迭代的過(guò)程中發(fā)現(xiàn)被修改,就會(huì)拋出ConcurrentModificationException。

并發(fā)容器:

1、主要代表有ConcurrentHashMap、CopyOnWriteArrayList、ConcurrentSkipListMap、ConcurrentSkipListSet。

2、鎖的粒度是分散的、細(xì)粒度的,即讀和寫(xiě)是使?不同的鎖。

3、迭代器具有弱?致性,即可以容忍并發(fā)修改,不會(huì)拋出ConcurrentModificationException。

  • ConcurrentHashMap 采?分段鎖技術(shù),同步容器中,是?個(gè)容器?個(gè)鎖,但在ConcurrentHashMap中,會(huì)將hash表的數(shù)組部分分成若?段,每段維護(hù)?個(gè)鎖,以達(dá)到?效的并發(fā)訪問(wèn);

13 什么是多線程的上下?切換?

1、多線程:是指從軟件或者硬件上實(shí)現(xiàn)多個(gè)線程的并發(fā)技術(shù)。

2、多線程的好處:

  • 使?多線程可以把程序中占據(jù)時(shí)間?的任務(wù)放到后臺(tái)去處理,如圖?、視屏的下載 發(fā)揮多核處理器的優(yōu)勢(shì),并發(fā)執(zhí)?讓系統(tǒng)運(yùn)?的更快、更流暢,?戶體驗(yàn)更好

3、多線程的缺點(diǎn):

  • ?量的線程降低代碼的可讀性;更多的線程需要更多的內(nèi)存空間, 當(dāng)多個(gè)線程對(duì)同?個(gè)資源出現(xiàn)爭(zhēng)奪時(shí)候要注意線程安全的問(wèn)題。

4、多線程的上下?切換:

  • CPU通過(guò)時(shí)間?分配算法來(lái)循環(huán)執(zhí)?任務(wù),當(dāng)前任務(wù)執(zhí)??個(gè)時(shí)間?后會(huì)切換到下?個(gè)任務(wù)。但是,在切換前會(huì)保存上?個(gè)任務(wù)的狀態(tài),以便下次切換回這個(gè)任務(wù)時(shí),可以再次加載這個(gè)任務(wù)的狀態(tài)。

14 ThreadLocal的設(shè)計(jì)理念與作??

Java中的ThreadLocal類(lèi)允許我們創(chuàng)建只能被同?個(gè)線程讀寫(xiě)的變量。因此,如果?段代碼含有?個(gè)ThreadLocal變量的引?,即使兩個(gè)線程同時(shí)執(zhí)?這段代碼,它們也?法訪問(wèn)到對(duì)?的ThreadLocal變量。

概念:線程局部變量。在并發(fā)編程的時(shí)候,成員變量如果不做任何處理其實(shí)是線程不安全的,各個(gè)線程都在操作同?個(gè)變量,顯然是不?的,并且我們也知道volatile這個(gè)關(guān)鍵字也是不能保證線程安全的。那么在有?種情況之下,我們需要滿?這樣?個(gè)條件:變量是同?個(gè),但是每個(gè)線程都使?同?個(gè)初始值,也就是使?同?個(gè)變量的?個(gè)新的副本。這種情況之下ThreadLocal就?常適?,?如說(shuō)DAO的數(shù)據(jù)庫(kù)連接,我們知道DAO是單例的,那么他的屬性Connection就不是?個(gè)線程安全的變量。?我們每個(gè)線程都需要使?他,并且各自使?各自的。這種情況,ThreadLocal就?較好的解決了這個(gè)問(wèn)題。

原理:從本質(zhì)來(lái)講,就是每個(gè)線程都維護(hù)了?個(gè)map,?這個(gè)map的key就threadLocal,?值就是我們set的那個(gè)值,每次線程在get的時(shí)候,都從自?的變量中取值,既然從自?的變量中取值,那肯定就不存在線程安全問(wèn)題,總體來(lái)講,ThreadLocal這個(gè)變量的狀態(tài)根本沒(méi)有發(fā)?變化,他僅僅是充當(dāng)?個(gè)key的??,另外提供給每?個(gè)線程?個(gè)初始值。

實(shí)現(xiàn)機(jī)制:每個(gè)Thread對(duì)象內(nèi)部都維護(hù)了?個(gè)ThreadLocalMap這樣?個(gè)ThreadLocal的Map,可以存放若?個(gè) ThreadLocal。

15 ThreadPool(線程池)?法與優(yōu)勢(shì)?

ThreadPool 優(yōu)點(diǎn):

減少了創(chuàng)建和銷(xiāo)毀線程的次數(shù),每個(gè)?作線程都可以被重復(fù)利?,可執(zhí)?多個(gè)任務(wù) 可以根據(jù)系統(tǒng)的承受能?,調(diào)整線程池中?作線線程的數(shù)?,防?因?yàn)橐驗(yàn)橄倪^(guò)多的內(nèi)存,?把服務(wù)器累趴下(每個(gè)線程需要?約1MB內(nèi)存,線程開(kāi)的越多,消耗的內(nèi)存也就越?,最后死機(jī))

------減少在創(chuàng)建和銷(xiāo)毀線程上所花的時(shí)間以及系統(tǒng)資源的開(kāi)銷(xiāo)

------如不使?線程池,有可能造成系統(tǒng)創(chuàng)建?量線程?導(dǎo)致消耗完系統(tǒng)內(nèi)存

  • Java??線程池的頂級(jí)接?是Executor,但是嚴(yán)格意義上講Executor并不是?個(gè)線程池,?只是?個(gè)執(zhí)?線程的?具。真正的線程池接?是ExecutorService。

當(dāng)線程數(shù)?于corePoolSize時(shí),創(chuàng)建線程執(zhí)?任務(wù)。

當(dāng)線程數(shù)?于等于corePoolSize并且workQueue沒(méi)有滿時(shí),放?workQueue中

線程數(shù)?于等于corePoolSize并且當(dāng)workQueue滿時(shí),新任務(wù)新建線程運(yùn)?,線程總數(shù)要?于maximumPoolSize

當(dāng)線程總數(shù)等于maximumPoolSize并且workQueue滿了的時(shí)候執(zhí)?handler的rejectedExecution。也就是拒絕策略。

16 Concurrent包?的其他東?:ArrayBlockingQueue、CountDownLatch等等。

1、ArrayBlockingQueue 數(shù)組結(jié)構(gòu)組成的有界阻塞隊(duì)列。

2、CountDownLatch 允許?個(gè)或多個(gè)線程等待其他線程完成操作;join?于讓當(dāng)前執(zhí)?線程等待join線程執(zhí)?結(jié)束。其實(shí)現(xiàn)原理是不停檢查join線程是否存活,如果join線程存活則讓當(dāng)前線程永遠(yuǎn)wait。

17 synchronized和ReentrantLock的區(qū)別?

基礎(chǔ)知識(shí):

1.可重?鎖??芍?鎖是指同?個(gè)線程可以多次獲取同?把鎖。ReentrantLocksynchronized都是可重?鎖。

2.可中斷鎖??芍袛噫i是指線程嘗試獲取鎖的過(guò)程中,是否可以響應(yīng)中斷。synchronized是不可中斷鎖,?ReentrantLock則提供了中斷功能。公平鎖與?公平鎖。公平鎖是指多個(gè)線程同時(shí)嘗試獲取同?把鎖時(shí),獲取鎖的順序按照線程達(dá)到的順序,??公平鎖則允許線程“插隊(duì)”。synchronized是?公平鎖,?ReentrantLock的默認(rèn)實(shí)現(xiàn)是?公平鎖,但是也可以設(shè)置為公平鎖。

3.CAS操作(CompareAndSwap)。CAS操作簡(jiǎn)單的說(shuō)就是?較并交換。CAS 操作包含三個(gè)操作數(shù) —— 內(nèi)存位置(V)、預(yù)期原值(A)和新值(B)。如果內(nèi)存位置的值與預(yù)期原值相匹配,那么處理器會(huì)自動(dòng)將該位置值更新為新值。否則,處理器不做任何操作。?論哪種情況,它都會(huì)在 CAS 指令之前返回該位置的值。CAS 有效地說(shuō)明了“我認(rèn)為位置 V 應(yīng)該包含值 A;如果包含該值,則將 B 放到這個(gè)位置;否則,不要更改該位置,只告訴我這個(gè)位置現(xiàn)在的值即可?!?/p>

4.Synchronized: isynchronized是java內(nèi)置的關(guān)鍵字,它提供了?種獨(dú)占的加鎖?式。synchronized的獲取和釋放鎖由JVM實(shí)現(xiàn),?戶不需要顯示的釋放鎖,?常?便。然?synchronized也有?定的局限性:

當(dāng)線程嘗試獲取鎖的時(shí)候,如果獲取不到鎖會(huì)?直阻塞。

如果獲取鎖的線程進(jìn)?休眠或者阻塞,除?當(dāng)前線程異常,否則其他線程嘗試獲取鎖必須?直等待。

5.ReentrantLock:

ReentrantLock它是JDK 1.5之后提供的API層?的互斥鎖,需要lock()和unlock()?法配合try/finally語(yǔ)句塊來(lái)完成。

等待可中斷避免,出現(xiàn)死鎖的情況(如果別的線程正持有鎖,會(huì)等待參數(shù)給定的時(shí)間,在等待的過(guò)程中,如果獲取了鎖定,就返回true,如果等待超時(shí),返回false)

公平鎖與?公平鎖多個(gè)線程等待同?個(gè)鎖時(shí),必須按照申請(qǐng)鎖的時(shí)間順序獲得鎖,Synchronized鎖?公平鎖,ReentrantLock默認(rèn)的構(gòu)造函數(shù)是創(chuàng)建的?公平鎖,可以通過(guò)參數(shù)true設(shè)為公平鎖,但公平鎖表現(xiàn)的性能不是很好。

18 Semaphore有什么作??

Semaphore就是?個(gè)信號(hào)量,它的作?是限制某段代碼塊的并發(fā)數(shù)

19 Java Concurrency API中的Lock接?(Lock interface)是什么?對(duì)?同步它有什么優(yōu)勢(shì)?

1、Lock接??同步?法和同步塊提供了更具擴(kuò)展性的鎖操作。他們?cè)试S更靈活的結(jié)構(gòu),可以具有完全不同的性質(zhì),并且可以?持多個(gè)相關(guān)類(lèi)的條件對(duì)象。

2、它的優(yōu)勢(shì)有:

可以使鎖更公平 可以使線程在等待鎖的時(shí)候響應(yīng)中斷 可以讓線程嘗試獲取鎖,并在?法獲取鎖的時(shí)候?即返回或者等待?段時(shí)間 可以在不同的范圍,以不同的順序獲取和釋放鎖

20 Hashtable的size()?法中明明只有?條語(yǔ)句”return count”,為什么還要做同步?

1、同?時(shí)間只能有?條線程執(zhí)?固定類(lèi)的同步?法,但是對(duì)于類(lèi)的?同步?法,可以多條線程同時(shí)訪問(wèn)。所以,這樣就有問(wèn)題了,可能線程A在執(zhí)?Hashtable的put?法添加數(shù)據(jù),線程B則可以正常調(diào)?size()?法讀取Hashtable中當(dāng)前元素的個(gè)數(shù),那讀取到的值可能不是最新的,可能線程A添加了完了數(shù)據(jù),但是沒(méi)有對(duì)size++,線程B就已經(jīng)讀取size了,那 么對(duì)于線程B來(lái)說(shuō)讀取到的size?定是不準(zhǔn)確的。

2、?給size()?法加了同步之后,意味著線程B調(diào)?size()?法只有在線程A調(diào)?put?法完畢之后才可以調(diào)?,這樣就保證了線程安全性。

21 ConcurrentHashMap的并發(fā)度是什么?

1、?作機(jī)制(分?思想):它引?了?個(gè)“分段鎖”的概念,具體可以理解為把?個(gè)?的Map拆分成N個(gè)?的segment,根據(jù)key.hashCode()來(lái)決定把key放到哪個(gè)HashTable中??梢蕴峁┫嗤木€程安全,但是效率提升N倍,默認(rèn)提升16倍。

2、應(yīng)?:當(dāng)讀>寫(xiě)時(shí)使?,適合做緩存,在程序啟動(dòng)時(shí)初始化,之后可以被多個(gè)線程訪問(wèn);

3、hash沖突:

簡(jiǎn)介:HashMap中調(diào)?hashCode()?法來(lái)計(jì)算hashCode。由于在Java中兩個(gè)不同的對(duì)象可能有?樣的hashCode,所以不同的鍵可能有?樣hashCode,從?導(dǎo)致沖突的產(chǎn)?。hash沖突解決:使?平衡樹(shù)來(lái)代替鏈表,當(dāng)同?hash中的元素?cái)?shù)量超過(guò)特定的值便會(huì)由鏈表切換到平衡樹(shù)

4、?鎖讀:ConcurrentHashMap之所以有較好的并發(fā)性是因?yàn)镃oncurrentHashMap是?鎖讀和加鎖寫(xiě),并且利?了分段鎖(不是在所有的entry上加鎖,?是在?部分entry上加鎖);

讀之前會(huì)先判斷count(jdk1.6),其中的count是被volatile修飾的(當(dāng)變量被volatile修飾后,每次更改該變量的時(shí)候會(huì)將更改結(jié)果寫(xiě)到系統(tǒng)主內(nèi)存中,利?多處理器的緩存?致性,其他處理器會(huì)發(fā)現(xiàn)自?的緩存?對(duì)應(yīng)的內(nèi)存地址被修改,就會(huì)將自?處理器的緩存?設(shè)置為失效,并強(qiáng)制從系統(tǒng)主內(nèi)存獲取最新的數(shù)據(jù)。),故可以實(shí)現(xiàn)?鎖讀。

5、ConcurrentHashMap的并發(fā)度就是segment的??,默認(rèn)為16,這意味著最多同時(shí)可以有16條線程操作ConcurrentHashMap,這也是ConcurrentHashMap對(duì)Hashtable的最?優(yōu)勢(shì)。

22 ReentrantReadWriteLock讀寫(xiě)鎖的使??

1、讀寫(xiě)鎖:分為讀鎖和寫(xiě)鎖,多個(gè)讀鎖不互斥,讀鎖與寫(xiě)鎖互斥,這是由jvm自?控制的,你只要上好相應(yīng)的鎖即可。

2、如果你的代碼只讀數(shù)據(jù),可以很多?同時(shí)讀,但不能同時(shí)寫(xiě),那就上讀鎖;

3、如果你的代碼修改數(shù)據(jù),只能有?個(gè)?在寫(xiě),且不能同時(shí)讀取,那就上寫(xiě)鎖。總之,讀的時(shí)候上讀鎖,寫(xiě)的時(shí)候上寫(xiě)鎖!

23 CyclicBarrier和CountDownLatch的?法及區(qū)別?

CyclicBarrier和CountDownLatch 都位于java.util.concurrent 這個(gè)包下

24 LockSupport?具?

LockSupport是JDK中?較底層的類(lèi),?來(lái)創(chuàng)建鎖和其他同步?具類(lèi)的基本線程阻塞。java鎖和同步器框架的核? AQS:AbstractQueuedSynchronizer,就是通過(guò)調(diào)? LockSupport .park()和 LockSupport .unpark()實(shí)現(xiàn)線程的阻塞和喚醒的。

25 Condition接?及其實(shí)現(xiàn)原理?

在java.util.concurrent包中,有兩個(gè)很特殊的?具類(lèi),Condition和ReentrantLock,使?過(guò)的?都知道,ReentrantLock(重?鎖)是jdk的concurrent包提供的?種獨(dú)占鎖的實(shí)現(xiàn)。

我們知道在線程的同步時(shí)可以使?個(gè)線程阻塞?等待?個(gè)信號(hào),同時(shí)放棄鎖使其他線程可以能競(jìng)爭(zhēng)到鎖。

在synchronized中我們可以使?Object的wait()和notify?法實(shí)現(xiàn)這種等待和喚醒。

但是在Lock中怎么實(shí)現(xiàn)這種wait和notify呢?答案是Condition,學(xué)習(xí)Condition主要是為了?便以后學(xué)習(xí)blockqueue和concurrenthashmap的源碼,同時(shí)也進(jìn)?步理解ReentrantLock。

26 Fork/Join框架的理解?

1、Fork就是把?個(gè)?任務(wù)切分為若??任務(wù)并?的執(zhí)?。

2、Join就是合并這些?任務(wù)的執(zhí)?結(jié)果,最后得到這個(gè)?任務(wù)的結(jié)果。

27 wait()和sleep()的區(qū)別?

1、sleep() ?法是線程類(lèi)(Thread)的靜態(tài)?法,讓調(diào)?線程進(jìn)?睡眠狀態(tài),讓出執(zhí)?機(jī)會(huì)給其他線程,等到休眠時(shí)間結(jié)束后,線程進(jìn)?就緒狀態(tài)和其他線程?起競(jìng)爭(zhēng)cpu的執(zhí)?時(shí)間。

因?yàn)閟leep() 是static靜態(tài)的?法,他不能改變對(duì)象的機(jī)鎖,當(dāng)?個(gè)synchronized塊中調(diào)?了sleep() ?法,線程雖然進(jìn)?休眠,但是對(duì)象的機(jī)鎖沒(méi)有被釋放,其他線程依然?法訪問(wèn)這個(gè)對(duì)象。

2、wait() wait()是Object類(lèi)的?法,當(dāng)?個(gè)線程執(zhí)?到wait?法時(shí),它就進(jìn)?到?個(gè)和該對(duì)象相關(guān)的等待池,同時(shí)釋放對(duì)象的機(jī)鎖,使得其他線程能夠訪問(wèn),可以通過(guò)notify,notifyAll?法來(lái)喚醒等待的線程。

28 線程的五個(gè)狀態(tài)(五種狀態(tài),創(chuàng)建、就緒、運(yùn)?、阻塞和死亡)?

線程通常都有五種狀態(tài),創(chuàng)建、就緒、運(yùn)?、阻塞和死亡。

第?是創(chuàng)建狀態(tài)。在?成線程對(duì)象,并沒(méi)有調(diào)?該對(duì)象的start?法,這是線程處于創(chuàng)建狀態(tài)。

第?是就緒狀態(tài)。當(dāng)調(diào)?了線程對(duì)象的start?法之后,該線程就進(jìn)?了就緒狀態(tài),但是此時(shí)線程調(diào)度程序還沒(méi)有把該線程設(shè)置為當(dāng)前線程,此時(shí)處于就緒狀態(tài)。在線程運(yùn)?之后,從等待或者睡眠中回來(lái)之后,也會(huì)處于就緒狀態(tài) 。第三是運(yùn)?狀態(tài)。線程調(diào)度程序?qū)⑻幱诰途w狀態(tài)的線程設(shè)置為當(dāng)前線程,此時(shí)線程就進(jìn)?了運(yùn)?狀態(tài),開(kāi)始運(yùn)?run函數(shù)當(dāng)中的代碼。

第四是阻塞狀態(tài)。線程正在運(yùn)?的時(shí)候,被暫停,通常是為了等待某個(gè)時(shí)間的發(fā)?(?如說(shuō)某項(xiàng)資源就緒)之后再繼續(xù)運(yùn)?。sleep,suspend,wait等?法都可以導(dǎo)致線程阻塞。

第五是死亡狀態(tài)。如果?個(gè)線程的run?法執(zhí)?結(jié)束或者調(diào)?stop?法后,該線程就會(huì)死亡。對(duì)于已經(jīng)死亡的線程,?法再使?start?法令其進(jìn)?就緒。

29 start()?法和run()?法的區(qū)別?

1、start()?法來(lái)啟動(dòng)?個(gè)線程,真正實(shí)現(xiàn)了多線程運(yùn)?。

2、如果直接調(diào)?run(),其實(shí)就相當(dāng)于是調(diào)?了?個(gè)普通函數(shù)?已,直接調(diào)?run()?法必須等待run()?法執(zhí)?完畢才能執(zhí)?下?的代碼,所以執(zhí)?路徑還是只有?條,根本就沒(méi)有線程的特征,所以在多線程執(zhí)?時(shí)要使?start()?法?不是run()?法。

30 Runnable接?和Callable接?的區(qū)別?

Runnable接?中的run()?法的返回值是void,它做的事情只是純粹地去執(zhí)?run()?法中的代碼?已;

Callable接?中的call()?法是有返回值的,是?個(gè)泛型,和Future、FutureTask配合可以?來(lái)獲取異步執(zhí)?的結(jié)果。

31 volatile關(guān)鍵字的作??

多線程主要圍繞可?性和原?性兩個(gè)特性?展開(kāi),使?volatile關(guān)鍵字修飾的變量,保證了其在多線程之間的可?性,即每次讀取到volatile變量,?定是最新的數(shù)據(jù)。

代碼底層執(zhí)?不像我們看到的?級(jí)語(yǔ)?—-Java程序這么簡(jiǎn)單,它的執(zhí)?是Java代碼–>字節(jié)碼–>根據(jù)字節(jié)碼執(zhí)?對(duì)應(yīng)的C/C++代碼–>C/C++代碼被編譯成匯編語(yǔ)?–>和硬件電路交互,現(xiàn)實(shí)中,為了獲取更好的性能JVM可能會(huì)對(duì)指令進(jìn)?重排序,多線程下可能會(huì)出現(xiàn)?些意想不到的問(wèn)題。使?volatile則會(huì)對(duì)禁?語(yǔ)義重排序,當(dāng)然這也?定程度上降低了代碼執(zhí)?效率。

32 Java中如何獲取到線程dump?件?

死循環(huán)、死鎖、阻塞、??打開(kāi)慢等問(wèn)題,查看線程dump是最好的解決問(wèn)題的途徑。所謂線程dump也就是線程堆棧,獲取到線程堆棧有兩步:

獲取到線程的pid,可以通過(guò)使?jps命令,在Linux環(huán)境下還可以使?ps -ef | grep java

打印線程堆棧,可以通過(guò)使?jstack pid命令,在Linux環(huán)境下還可以使?kill -3 pid

另外提?點(diǎn),Thread類(lèi)提供了?個(gè)getStackTrace()?法也可以?于獲取線程堆棧。這是?個(gè)實(shí)例?法,因此此?法是和具體線程實(shí)例綁定的,每次獲取到的是具體某個(gè)線程當(dāng)前運(yùn)?的堆棧。

33 線程和進(jìn)程有什么區(qū)別?

進(jìn)程是系統(tǒng)進(jìn)?資源分配的基本單位,有獨(dú)?的內(nèi)存地址空間

線程是CPU獨(dú)?運(yùn)?和獨(dú)?調(diào)度的基本單位,沒(méi)有單獨(dú)地址空間,有獨(dú)?的棧,局部變量,寄存器, 程序計(jì)數(shù)器等。

創(chuàng)建進(jìn)程的開(kāi)銷(xiāo)?,包括創(chuàng)建虛擬地址空間等需要?量系統(tǒng)資源

創(chuàng)建線程開(kāi)銷(xiāo)?,基本上只有?個(gè)內(nèi)核對(duì)象和?個(gè)堆棧。

?個(gè)進(jìn)程?法直接訪問(wèn)另?個(gè)進(jìn)程的資源;同?進(jìn)程內(nèi)的多個(gè)線程共享進(jìn)程的資源。

進(jìn)程切換開(kāi)銷(xiāo)?,線程切換開(kāi)銷(xiāo)?;進(jìn)程間通信開(kāi)銷(xiāo)?,線程間通信開(kāi)銷(xiāo)?。

線程屬于進(jìn)程,不能獨(dú)?執(zhí)?。每個(gè)進(jìn)程?少要有?個(gè)線程,成為主線程

34 線程實(shí)現(xiàn)的?式有?種(四種)?

繼承Thread類(lèi),重寫(xiě)run?法

實(shí)現(xiàn)Runnable接?,重寫(xiě)run?法,實(shí)現(xiàn)Runnable接?的實(shí)現(xiàn)類(lèi)的實(shí)例對(duì)象作為T(mén)hread構(gòu)造函數(shù)的target

實(shí)現(xiàn)Callable接?通過(guò)FutureTask包裝器來(lái)創(chuàng)建Thread線程

通過(guò)線程池創(chuàng)建線程

35 高并發(fā)、任務(wù)執(zhí)?時(shí)間短的業(yè)務(wù)怎樣使?線程池?并發(fā)不?、任務(wù)執(zhí)?時(shí)間?的業(yè)務(wù)怎樣使?線程池?并發(fā)?業(yè)務(wù)執(zhí)?時(shí)間?的業(yè)務(wù)怎樣使?線程池?

高并發(fā)、任務(wù)執(zhí)?時(shí)間短的業(yè)務(wù):線程池線程數(shù)可以設(shè)置為CPU核數(shù)+1,減少線程上下?的切換。

并發(fā)不?、任務(wù)執(zhí)?時(shí)間?的業(yè)務(wù)要區(qū)分開(kāi)看:

  1. 假如是業(yè)務(wù)時(shí)間?集中在IO操作上,也就是IO密集型的任務(wù),因?yàn)镮O操作并不占?CPU,所以不要讓所有的CPU閑下來(lái),可以加?線程池中的線程數(shù)?,讓CPU處理更多的業(yè)務(wù)
  2. 假如是業(yè)務(wù)時(shí)間?集中在計(jì)算操作上,也就是計(jì)算密集型任務(wù),這個(gè)就沒(méi)辦法了,和(1)?樣吧,線程池中的線程數(shù)設(shè)置得少?些,減少線程上下?的切換

并發(fā)?、業(yè)務(wù)執(zhí)?時(shí)間?,解決這種類(lèi)型任務(wù)的關(guān)鍵不在于線程池?在于整體架構(gòu)的設(shè)計(jì),看看這些業(yè)務(wù)??某些數(shù)據(jù)是否能做緩存是第?步,增加服務(wù)器是第?步,?于線程池的設(shè)置,設(shè)置參考(2)。最后,業(yè)務(wù)執(zhí)?時(shí)間?的問(wèn)題, 也可能需要分析?下,看看能不能使?中間件對(duì)任務(wù)進(jìn)?拆分和解耦。

36 如果你提交任務(wù)時(shí),線程池隊(duì)列已滿,這時(shí)會(huì)發(fā)?什么?

1、如果你使?的LinkedBlockingQueue,也就是?界隊(duì)列的話,沒(méi)關(guān)系,繼續(xù)添加任務(wù)到阻塞隊(duì)列中等待執(zhí)?,因?yàn)長(zhǎng)inkedBlockingQueue可以近乎認(rèn)為是?個(gè)?窮?的隊(duì)列,可以?限存放任務(wù);

2、如果你使?的是有界隊(duì)列??說(shuō)ArrayBlockingQueue的話,任務(wù)?先會(huì)被添加到ArrayBlockingQueue中,ArrayBlockingQueue滿了,則會(huì)使?拒絕策略RejectedExecutionHandler處理滿了的任務(wù),默認(rèn)是AbortPolicy。

37 鎖的等級(jí):?法鎖、對(duì)象鎖、類(lèi)鎖?

?法鎖(synchronized修飾?法時(shí)):

通過(guò)在?法聲明中加? synchronized關(guān)鍵字來(lái)聲明 synchronized ?法。

synchronized ?法控制對(duì)類(lèi)成員變量的訪問(wèn);

每個(gè)類(lèi)實(shí)例對(duì)應(yīng)?把鎖,每個(gè) synchronized ?法都必須獲得調(diào)?該?法的類(lèi)實(shí)例的鎖?能執(zhí)?,否則所屬線程阻塞,?法?旦執(zhí)?,就獨(dú)占該鎖,直到從該?法返回時(shí)才將鎖釋放,此后被阻塞的線程?能獲得該鎖,重新進(jìn)?可執(zhí)?狀態(tài)。這種機(jī)制確保了同?時(shí)刻對(duì)于每?個(gè)類(lèi)實(shí)例,其所有聲明為 synchronized 的成員函數(shù)中?多只有?個(gè)處于可執(zhí)?狀態(tài),從?有效避免了類(lèi)成員變量的訪問(wèn)沖突。

對(duì)象鎖(synchronized修飾?法或代碼塊):

當(dāng)?個(gè)對(duì)象中有synchronized method或synchronized block的時(shí)候調(diào)?此對(duì)象的同步?法或進(jìn)?其同步區(qū)域時(shí),就必須先獲得對(duì)象鎖。如果此對(duì)象的對(duì)象鎖已被其他調(diào)?者占?,則需要等待此鎖被釋放。(?法鎖也是對(duì)象鎖)

java的所有對(duì)象都含有1個(gè)互斥鎖,這個(gè)鎖由JVM自動(dòng)獲取和釋放。線程進(jìn)?synchronized?法的時(shí)候獲取該對(duì)象的鎖,當(dāng)然如果已經(jīng)有線程獲取了這個(gè)對(duì)象的鎖,那么當(dāng)前線程會(huì)等待;synchronized?法正常返回或者拋異常?終?,JVM會(huì)自動(dòng)釋放對(duì)象鎖。這?也體現(xiàn)了?synchronized來(lái)加鎖的1個(gè)好處,?法拋異常的時(shí)候,鎖仍然可以由JVM來(lái)自動(dòng)釋放。

類(lèi)鎖(synchronized 修飾靜態(tài)的?法或代碼塊):

由于?個(gè)class不論被實(shí)例化多少次,其中的靜態(tài)?法和靜態(tài)變量在內(nèi)存中都只有?份。所以,?旦?個(gè)靜態(tài)的?法被申明為synchronized。此類(lèi)所有的實(shí)例化對(duì)象在調(diào)?此?法,共?同?把鎖,我們稱之為類(lèi)鎖。

對(duì)象鎖是?來(lái)控制實(shí)例?法之間的同步,類(lèi)鎖是?來(lái)控制靜態(tài)?法(或靜態(tài)變量互斥體)之間的同步

38 如果同步塊內(nèi)的線程拋出異常會(huì)發(fā)?什么?

synchronized?法正常返回或者拋異常?終?,JVM會(huì)自動(dòng)釋放對(duì)象鎖

39 并發(fā)編程(concurrency)并?編程(parallellism)有什么區(qū)別?

解釋?:并?是指兩個(gè)或者多個(gè)事件在同?時(shí)刻發(fā)?;?并發(fā)是指兩個(gè)或多個(gè)事件在同?時(shí)間間隔發(fā)?。

解釋?:并?是在不同實(shí)體上的多個(gè)事件,并發(fā)是在同?實(shí)體上的多個(gè)事件。

解釋三:在?臺(tái)處理器上“同時(shí)”處理多個(gè)任務(wù),在多臺(tái)處理器上同時(shí)處理多個(gè)任務(wù)。如hadoop分布式集群所以并發(fā)編程的?標(biāo)是充分的利?處理器的每?個(gè)核,以達(dá)到最?的處理性能。

40 如何保證多線程下 i++ 結(jié)果正確?

volatile只能保證你數(shù)據(jù)的可?性,獲取到的是最新的數(shù)據(jù),不能保證原?性;

?AtomicInteger保證原?性。

synchronized既能保證共享變量可?性,也可以保證鎖內(nèi)操作的原?性。

41 ?個(gè)線程如果出現(xiàn)了運(yùn)?時(shí)異常會(huì)怎么樣?

如果這個(gè)異常沒(méi)有被捕獲的話,這個(gè)線程就停?執(zhí)?了。

另外重要的?點(diǎn)是:如果這個(gè)線程持有某個(gè)對(duì)象的監(jiān)視器,那么這個(gè)對(duì)象監(jiān)視器會(huì)被?即釋放.

42 如何在兩個(gè)線程之間共享數(shù)據(jù)?

通過(guò)在線程之間共享對(duì)象就可以了,然后通過(guò)wait/notify/notifyAll、await/signal/signalAll進(jìn)?喚起和等待,??說(shuō)阻塞隊(duì)列BlockingQueue就是為線程之間共享數(shù)據(jù)?設(shè)計(jì)的。

43 ?產(chǎn)者消費(fèi)者模型的作?是什么?

通過(guò)平衡?產(chǎn)者的?產(chǎn)能?和消費(fèi)者的消費(fèi)能?來(lái)提升整個(gè)系統(tǒng)的運(yùn)?效率,這是?產(chǎn)者消費(fèi)者模型最重要的作?。

解耦,這是?產(chǎn)者消費(fèi)者模型附帶的作?,解耦意味著?產(chǎn)者和消費(fèi)者之間的聯(lián)系少,聯(lián)系越少越可以獨(dú)自發(fā)展?不需要受到相互的制約。

44 怎么喚醒?個(gè)阻塞的線程?

如果線程是因?yàn)檎{(diào)?了wait()、sleep()或者join()?法?導(dǎo)致的阻塞;

suspend與resume:Java廢棄 suspend() 去掛起線程的原因,是因?yàn)?suspend() 在導(dǎo)致線程暫停的同時(shí),并不會(huì)去釋放任何鎖資源。其他線程都?法訪問(wèn)被它占?的鎖。直到對(duì)應(yīng)的線程執(zhí)? resume() ?法后,被掛起的線程才能繼續(xù),從?其它被阻塞在這個(gè)鎖的線程才可以繼續(xù)執(zhí)?。但是,如果 resume() 操作出現(xiàn)在 suspend() 之前執(zhí)?,那么線程將?直處于掛起狀態(tài),同時(shí)?直占?鎖,這就產(chǎn)?了死鎖。?且,對(duì)于被掛起的線程,它的線程狀態(tài)居然還是 Runnable。

wait與notify:wait與notify必須配合synchronized使?,因?yàn)檎{(diào)?之前必須持有鎖,wait會(huì)?即釋放鎖,notify則是同步塊執(zhí)?完了才釋放

await與singal:Condition類(lèi)提供,?Condition對(duì)象由new ReentLock().newCondition()獲得,與wait和notify相同,因?yàn)槭?Lock鎖后?法使?wait?法

park與unpark:LockSupport是?個(gè)?常?便實(shí)?的線程阻塞?具,它可以在線程任意位置讓線程阻塞。和Thread.suspenf()相?,它彌補(bǔ)了由于resume()在前發(fā)?,導(dǎo)致線程?法繼續(xù)執(zhí)?的情況。和Object.wait()相?,它不需要先獲得某個(gè)對(duì)象的鎖,也不會(huì)拋出IException異常??梢詥拘阎付ň€程。如果線程遇到了IO阻塞,?能為?,因?yàn)镮O是操作系統(tǒng)實(shí)現(xiàn)的,Java代碼并沒(méi)有辦法直接接觸到操作系統(tǒng)。

45 Java中?到的線程調(diào)度算法是什么?

搶占式。?個(gè)線程?完CPU之后,操作系統(tǒng)會(huì)根據(jù)線程優(yōu)先級(jí)、線程饑餓情況等數(shù)據(jù)算出?個(gè)總的優(yōu)先級(jí)并分配下?個(gè)時(shí)間?給某個(gè)線程執(zhí)?。

46 單例模式的線程安全性?

??常談的問(wèn)題了,?先要說(shuō)的是單例模式的線程安全意味著:某個(gè)類(lèi)的實(shí)例在多線程環(huán)境下只會(huì)被創(chuàng)建?次出來(lái)。單例模式有很多種的寫(xiě)法,我總結(jié)?下:

(1)餓漢式單例模式的寫(xiě)法:線程安全

(2)懶漢式單例模式的寫(xiě)法:?線程安全

(3)雙檢鎖單例模式的寫(xiě)法:線程安全

47 線程類(lèi)的構(gòu)造?法、靜態(tài)塊是被哪個(gè)線程調(diào)?的?

線程類(lèi)的構(gòu)造?法、靜態(tài)塊是被new這個(gè)線程類(lèi)所在的線程所調(diào)?的,?run?法??的代碼才是被線程自身所調(diào)?的。

48 同步?法和同步塊,哪個(gè)是更好的選擇?

同步塊是更好的選擇,因?yàn)樗粫?huì)鎖住整個(gè)對(duì)象(當(dāng)然也可以讓它鎖住整個(gè)對(duì)象)。同步?法會(huì)鎖住整個(gè)對(duì)象,哪怕這個(gè)類(lèi)中有多個(gè)不相關(guān)聯(lián)的同步塊,這通常會(huì)導(dǎo)致他們停?執(zhí)?并需要等待獲得這個(gè)對(duì)象上的鎖。

synchronized(this)以及?static的synchronized?法(?于static synchronized?法請(qǐng)往下看),只能防?多個(gè)線程同時(shí)執(zhí)?同?個(gè)對(duì)象的同步代碼段。

如果要鎖住多個(gè)對(duì)象?法,可以鎖住?個(gè)固定的對(duì)象,或者鎖住這個(gè)類(lèi)的Class對(duì)象。

synchronized鎖住的是括號(hào)?的對(duì)象,?不是代碼。對(duì)于?static的synchronized?法,鎖的就是對(duì)象本身也就是this。

49 如何檢測(cè)死鎖?怎么預(yù)防死鎖?

概念:是指兩個(gè)或兩個(gè)以上的進(jìn)程在執(zhí)?過(guò)程中,因爭(zhēng)奪資源?造成的?種互相等待的現(xiàn)象,若?外?作?,它們都將?法推進(jìn)下去。此時(shí)稱系統(tǒng)處于死鎖;

死鎖的四個(gè)必要條件:

互斥條件:進(jìn)程對(duì)所分配到的資源不允許其他進(jìn)程進(jìn)?訪問(wèn),若其他進(jìn)程訪問(wèn)該資源,只能等待,直?占有該資源的進(jìn)程使?完成后釋放該資源

請(qǐng)求和保持條件:進(jìn)程獲得?定的資源之后,?對(duì)其他資源發(fā)出請(qǐng)求,但是該資源可能被其他進(jìn)程占有,此時(shí)請(qǐng)求阻塞,但?對(duì)自?獲得的資源保持不放

不可剝奪條件:是指進(jìn)程已獲得的資源,在未完成使?之前,不可被剝奪,只能在使?完后自?釋放

環(huán)路等待條件:是指進(jìn)程發(fā)?死鎖后,若?進(jìn)程之間形成?種頭尾相接的循環(huán)等待資源關(guān)系

死鎖產(chǎn)?的原因:

因競(jìng)爭(zhēng)資源發(fā)?死鎖 現(xiàn)象:系統(tǒng)中供多個(gè)進(jìn)程共享的資源的數(shù)?不?以滿?全部進(jìn)程的需要時(shí),就會(huì)引起對(duì)諸資源的競(jìng)爭(zhēng)?發(fā)?死鎖現(xiàn)象

進(jìn)程推進(jìn)順序不當(dāng)發(fā)?死鎖

檢查死鎖:

有兩個(gè)容器,?個(gè)?于保存線程正在請(qǐng)求的鎖,?個(gè)?于保存線程已經(jīng)持有的鎖。每次加鎖之前都會(huì)做如下檢測(cè)

檢測(cè)當(dāng)前正在請(qǐng)求的鎖是否已經(jīng)被其它線程持有,如果有,則把那些線程找出來(lái)

遍歷第?步中返回的線程,檢查自?持有的鎖是否正被其中任何?個(gè)線程請(qǐng)求,如果第?步返回真,表示出現(xiàn)了死鎖

死鎖的解除與預(yù)防:

控制不要讓四個(gè)必要條件成?。

50 HashMap在多線程環(huán)境下使?需要注意什么?

要注意死循環(huán)的問(wèn)題,HashMap的put操作引發(fā)擴(kuò)容,這個(gè)動(dòng)作在多線程并發(fā)下會(huì)發(fā)?線程死循環(huán)的問(wèn)題。

1、HashMap不是線程安全的;Hashtable線程安全,但效率低,因?yàn)槭荋ashtable是使?synchronized的,所有線程競(jìng)爭(zhēng)同?把鎖;?ConcurrentHashMap不僅線程安全?且效率?,因?yàn)樗?個(gè)segment數(shù)組,將數(shù)據(jù)分段存儲(chǔ),給每?段數(shù)據(jù)配?把鎖,也就是所謂的鎖分段技術(shù)。

2、HashMap為何線程不安全:

put時(shí)key相同導(dǎo)致其中?個(gè)線程的value被覆蓋;

多個(gè)線程同時(shí)擴(kuò)容,造成數(shù)據(jù)丟失;

多線程擴(kuò)容時(shí)導(dǎo)致Node鏈表形成環(huán)形結(jié)構(gòu)造成.next()死循環(huán),導(dǎo)致CPU利?率接近100%;

3、ConcurrentHashMap最?效;

51 什么是守護(hù)線程?有什么??

守護(hù)線程(即daemon thread),是個(gè)服務(wù)線程,準(zhǔn)確地來(lái)說(shuō)就是服務(wù)其他的線程,這是它的作?——?其他的線程只有?種,那就是?戶線程。所以java?線程分2種,

1、守護(hù)線程,?如垃圾回收線程,就是最典型的守護(hù)線程。

2、?戶線程,就是應(yīng)?程序?的自定義線程。

52 如何實(shí)現(xiàn)線程串?執(zhí)??

a. 為了控制線程執(zhí)?的順序,如ThreadA->ThreadB->ThreadC->ThreadA循環(huán)執(zhí)?三個(gè)線程,我們需要確定喚醒、等待的順序。這時(shí)我們可以同時(shí)使? Obj.wait()、Obj.notify()與synchronized(Obj)來(lái)實(shí)現(xiàn)這個(gè)?標(biāo)。

線程中持有上?個(gè)線程類(lèi)的對(duì)象鎖以及自?的鎖,由于這種依賴關(guān)系,該線程執(zhí)?需要等待上個(gè)對(duì)象釋放鎖,從? 保證類(lèi)線程執(zhí)?的順序。

b. 通常情況下,wait是線程在獲取對(duì)象鎖后,主動(dòng)釋放對(duì)象鎖,同時(shí)本線程休眠,直到有其它線程調(diào)?對(duì)象的notify()喚醒該線程,才能繼續(xù)獲取對(duì)象鎖,并繼續(xù)執(zhí)?。?notify()則是對(duì)等待對(duì)象鎖的線程的喚醒操作。但值得注意的是notify()調(diào)?后,并不是?上就釋放對(duì)象鎖,?是在相應(yīng)的synchronized(){}語(yǔ)句塊執(zhí)?結(jié)束。釋放對(duì)象鎖后,JVM會(huì)在執(zhí)?wait()等待對(duì)象鎖的線程中隨機(jī)選取?線程,賦予其對(duì)象鎖,喚醒線程,繼續(xù)執(zhí)?。

53 可以運(yùn)?時(shí)kill掉?個(gè)線程嗎?

a. 不可以,線程有5種狀態(tài),新建(new)、可運(yùn)?(runnable)、運(yùn)?中(running)、阻塞(block)、死亡(dead)。

b. 只有當(dāng)線程run?法或者主線程main?法結(jié)束,?或者拋出異常時(shí),線程才會(huì)結(jié)束?命周期。

54 關(guān)于synchronized

在某個(gè)對(duì)象的所有synchronized?法中,在某個(gè)時(shí)刻只能有?個(gè)唯?的?個(gè)線程去訪問(wèn)這些synchronized?法

如果?個(gè)?法是synchronized?法,那么該synchronized關(guān)鍵字表示給當(dāng)前對(duì)象上鎖(即this)相當(dāng)于synchronized(this){}

如果?個(gè)synchronized?法是static的,那么該synchronized表示給當(dāng)前對(duì)象所對(duì)應(yīng)的class對(duì)象上鎖(每個(gè)類(lèi)不管?成多少對(duì)象,其對(duì)應(yīng)的class對(duì)象只有?個(gè))

55 分步式鎖,程序數(shù)據(jù)庫(kù)中死鎖機(jī)制及解決?案

基本原理:??個(gè)狀態(tài)值表示鎖,對(duì)鎖的占?和釋放通過(guò)狀態(tài)值來(lái)標(biāo)識(shí)。

三種分布式鎖:

第一種:Zookeeper:

基于zookeeper瞬時(shí)有序節(jié)點(diǎn)實(shí)現(xiàn)的分布式鎖,其主要邏輯如下。?致思想即為:每個(gè)客戶端對(duì)某個(gè)功能加鎖時(shí),在zookeeper上的與該功能對(duì)應(yīng)的指定節(jié)點(diǎn)的?錄下,?成?個(gè)唯?的瞬時(shí)有序節(jié)點(diǎn)。判斷是否獲取鎖的?式很簡(jiǎn)單,只需要判斷有序節(jié)點(diǎn)中序號(hào)最?的?個(gè)。當(dāng)釋放鎖的時(shí)候,只需將這個(gè)瞬時(shí)節(jié)點(diǎn)刪除即可。同時(shí),其可以避免服務(wù)宕機(jī)導(dǎo)致的鎖?法釋放,?產(chǎn)?的死鎖問(wèn)題

【優(yōu)點(diǎn)】鎖安全性?,zk可持久化,且能實(shí)時(shí)監(jiān)聽(tīng)獲取鎖的客戶端狀態(tài)。?旦客戶端宕機(jī),則瞬時(shí)節(jié)點(diǎn)隨之消失,zk因?能第?時(shí)間釋放鎖。這也省去了?分布式緩存實(shí)現(xiàn)鎖的過(guò)程中需要加?超時(shí)時(shí)間判斷的這?邏輯。

【缺點(diǎn)】性能開(kāi)銷(xiāo)?較?。因?yàn)槠湫枰獎(jiǎng)討B(tài)產(chǎn)?、銷(xiāo)毀瞬時(shí)節(jié)點(diǎn)來(lái)實(shí)現(xiàn)鎖功能。所以不太適合直接提供給?并發(fā)的場(chǎng)景使?。

【實(shí)現(xiàn)】可以直接采?zookeeper第三?庫(kù)curator即可?便地實(shí)現(xiàn)分布式鎖。

【適?場(chǎng)景】對(duì)可靠性要求?常?,且并發(fā)程度不?的場(chǎng)景下使?。如核?數(shù)據(jù)的定時(shí)全量/增量同步等。)

第二種memcached:

memcached帶有add函數(shù),利?add函數(shù)的特性即可實(shí)現(xiàn)分布式鎖。add和set的區(qū)別在于:如果多線程并發(fā)set,則每個(gè)set都會(huì)成功,但最后存儲(chǔ)的值以最后的set的線程為準(zhǔn)。?add的話則相反,add會(huì)添加第?個(gè)到達(dá)的值,并返回true,后續(xù)的添加則都會(huì)返回false。利?該點(diǎn)即可很輕松地實(shí)現(xiàn)分布式鎖。

【優(yōu)點(diǎn)】并發(fā)?效

【缺點(diǎn)】 memcached采?列?LRU置換策略,所以如果內(nèi)存不夠,可能導(dǎo)致緩存中的鎖信息丟失。memcached?法持久化,?旦重啟,將導(dǎo)致信息丟失。

【使?場(chǎng)景】?并發(fā)場(chǎng)景。需要 1)加上超時(shí)時(shí)間避免死鎖; 2)提供?夠?撐鎖服務(wù)的內(nèi)存空間; 3)穩(wěn)定的集群化管理。

第三種Redis:

redis分布式鎖即可以結(jié)合zk分布式鎖鎖?度安全和memcached并發(fā)場(chǎng)景下效率很好的優(yōu)點(diǎn),其實(shí)現(xiàn)?式和memcached類(lèi)似,采?setnx即可實(shí)現(xiàn)。需要注意的是,這?的redis也需要設(shè)置超時(shí)時(shí)間,以避免死鎖??梢岳?jedis客戶端實(shí)現(xiàn)。

數(shù)據(jù)庫(kù)死鎖機(jī)制和解決?案:

死鎖:死鎖是指兩個(gè)或者兩個(gè)以上的事務(wù)在執(zhí)?過(guò)程中,因爭(zhēng)奪鎖資源?造成的?種互相等待的現(xiàn)象。

處理機(jī)制:解決死鎖最有?最簡(jiǎn)單的?法是不要有等待,將任何等待都轉(zhuǎn)化為回滾,并且事務(wù)重新開(kāi)始。但是有可能影響并發(fā)性能。

------超時(shí)回滾,innodb_lock_wait_time設(shè)置超時(shí)時(shí)間;

------wait-for-graph?法:跟超時(shí)回滾?起來(lái),這是?種更加主動(dòng)的死鎖檢測(cè)?式。InnoDB引擎也采?這種?式。

56 spring單例為什么沒(méi)有安全問(wèn)題(ThreadLocal)

1、ThreadLocal:spring使?ThreadLocal解決線程安全問(wèn)題;ThreadLocal會(huì)為每?個(gè)線程提供?個(gè)獨(dú)?的變量副本,從?隔離了多個(gè)線程對(duì)數(shù)據(jù)的訪問(wèn)沖突。因?yàn)槊?個(gè)線程都擁有自?的變量副本,從?也就沒(méi)有必要對(duì)該變量進(jìn)?同步了。ThreadLocal提供了線程安全的共享對(duì)象,在編寫(xiě)多線程代碼時(shí),可以把不安全的變量封裝進(jìn)ThreadLocal。概括起來(lái)說(shuō),對(duì)于多線程資源共享的問(wèn)題,同步機(jī)制采?了“以時(shí)間換空間”的?式,?ThreadLocal采?了“以空間換時(shí)間”的?式。前者僅提供?份變量,讓不同的線程排隊(duì)訪問(wèn),?后者為每?個(gè)線程都提供了?份變量,因此可以同時(shí)訪問(wèn)?互不影響。在很多情況下,ThreadLocal?直接使?synchronized同步機(jī)制解決線程安全問(wèn)題更簡(jiǎn)單,更?便,且結(jié)果程序擁有更?的并發(fā)性。

2、單例:?狀態(tài)的Bean(?狀態(tài)就是?次操作,不能保存數(shù)據(jù)。?狀態(tài)對(duì)象(Stateless Bean),就是沒(méi)有實(shí)例變量的對(duì)象,不能保存數(shù)據(jù),是不變類(lèi),是線程安全的。)適合?不變模式,技術(shù)就是單例模式,這樣可以共享實(shí)例,提?性能。

57 線程池原理

使?場(chǎng)景:假設(shè)?個(gè)服務(wù)器完成?項(xiàng)任務(wù)所需時(shí)間為:T1-創(chuàng)建線程時(shí)間,T2-在線程中執(zhí)?任務(wù)的時(shí)間,T3-銷(xiāo)毀線程時(shí)間。如果T1+T3遠(yuǎn)?于T2,則可以使?線程池,以提?服務(wù)器性能;

組成:

線程池管理器(ThreadPool):?于創(chuàng)建并管理線程池,包括 創(chuàng)建線程池,銷(xiāo)毀線程池,添加新任務(wù);

?作線程(PoolWorker):線程池中線程,在沒(méi)有任務(wù)時(shí)處于等待狀態(tài),可以循環(huán)的執(zhí)?任務(wù);

任務(wù)接?(Task):每個(gè)任務(wù)必須實(shí)現(xiàn)的接?,以供?作線程調(diào)度任務(wù)的執(zhí)?,它主要規(guī)定了任務(wù)的??,任務(wù)執(zhí)?完后的收尾?作,任務(wù)的執(zhí)?狀態(tài)等;

任務(wù)隊(duì)列(taskQueue):?于存放沒(méi)有處理的任務(wù)。提供?種緩沖機(jī)制。

原理:線程池技術(shù)正是關(guān)注如何縮短或調(diào)整T1,T3時(shí)間的技術(shù),從?提?服務(wù)器程序性能的。它把T1,T3分別安排在服務(wù)器程序的啟動(dòng)和結(jié)束的時(shí)間段或者?些空閑的時(shí)間段,這樣在服務(wù)器程序處理客戶請(qǐng)求時(shí),不會(huì)有T1,T3的開(kāi)銷(xiāo)了。

?作流程:

1、線程池剛創(chuàng)建時(shí),??沒(méi)有?個(gè)線程(也可以設(shè)置參數(shù)prestartAllCoreThreads啟動(dòng)預(yù)期數(shù)量主線程)。任務(wù)隊(duì)列是作為參數(shù)傳進(jìn)來(lái)的。不過(guò),就算隊(duì)列??有任務(wù),線程池也不會(huì)?上執(zhí)?它們。

2、當(dāng)調(diào)? execute() ?法添加?個(gè)任務(wù)時(shí),線程池會(huì)做如下判斷:

如果正在運(yùn)?的線程數(shù)量?于 corePoolSize,那么?上創(chuàng)建線程運(yùn)?這個(gè)任務(wù);

如果正在運(yùn)?的線程數(shù)量?于或等于 corePoolSize,那么將這個(gè)任務(wù)放?隊(duì)列;

如果這時(shí)候隊(duì)列滿了,?且正在運(yùn)?的線程數(shù)量?于 maximumPoolSize,那么還是要?jiǎng)?chuàng)建?核?線程?刻運(yùn)?這個(gè)任務(wù);

如果隊(duì)列滿了,?且正在運(yùn)?的線程數(shù)量?于或等于 maximumPoolSize,那么線程池會(huì)拋出異常RejectExecutionException。

3、當(dāng)?個(gè)線程完成任務(wù)時(shí),它會(huì)從隊(duì)列中取下?個(gè)任務(wù)來(lái)執(zhí)?。

4、當(dāng)?個(gè)線程?事可做,超過(guò)?定的時(shí)間(keepAliveTime)時(shí),線程池會(huì)判斷,如果當(dāng)前運(yùn)?的線程數(shù)?于corePoolSize,那么這個(gè)線程就被停掉。所以線程池的所有任務(wù)完成后,它最終會(huì)收縮到 corePoolSize 的??。

58 java鎖多個(gè)對(duì)象

例如:在銀?系統(tǒng)轉(zhuǎn)賬時(shí),需要鎖定兩個(gè)賬戶,這個(gè)時(shí)候,順序使?兩個(gè)synchronized可能存在死鎖的情況

59 java線程如何啟動(dòng)

1、繼承Thread類(lèi);

2、實(shí)現(xiàn)Runnable接?;

3、直接在函數(shù)體內(nèi):

?較:

1、實(shí)現(xiàn)Runnable接?優(yōu)勢(shì):

1)適合多個(gè)相同的程序代碼的線程去處理同?個(gè)資源

2)可以避免java中的單繼承的限制

3)增加程序的健壯性,代碼可以被多個(gè)線程共享,代碼和數(shù)據(jù)獨(dú)?。

2、繼承Thread類(lèi)優(yōu)勢(shì):

1)可以將線程類(lèi)抽象出來(lái),當(dāng)需要使?抽象??模式設(shè)計(jì)時(shí)。

2)多線程同步

3、在函數(shù)體使?優(yōu)勢(shì)

1)?需繼承thread或者實(shí)現(xiàn)Runnable,縮?作?域。

60 java中加鎖的?式有哪些,如何實(shí)現(xiàn)怎么個(gè)寫(xiě)法?

1、java中有兩種鎖:?種是?法鎖或者對(duì)象鎖(在?靜態(tài)?法或者代碼塊上加鎖),第?種是類(lèi)鎖(在靜態(tài)?法或者class上加鎖);

2、注意:其他線程可以訪問(wèn)未加鎖的?法和代碼;synchronized同時(shí)修飾靜態(tài)?法和實(shí)例?法,但是運(yùn)?結(jié)果是交替進(jìn)?的,這證明了類(lèi)鎖和對(duì)象鎖是兩個(gè)不?樣的鎖,控制著不同的區(qū)域,它們是互不?擾的。

61 如何保證數(shù)據(jù)不丟失

1、使?消息隊(duì)列,消息持久化;

2、添加標(biāo)志位:未處理 0,處理中 1,已處理 2。定時(shí)處理。

62、ThreadLocal為什么會(huì)發(fā)?內(nèi)存泄漏?

1、OOM實(shí)現(xiàn):

ThreadLocal的實(shí)現(xiàn)是這樣的:每個(gè)Thread 維護(hù)?個(gè) ThreadLocalMap 映射表,這個(gè)映射表的 key 是 ThreadLocal實(shí)例本身,value 是真正需要存儲(chǔ)的 Object。2、也就是說(shuō) ThreadLocal 本身并不存儲(chǔ)值,它只是作為?個(gè) key 來(lái)讓線程從 ThreadLocalMap 獲取 value。值得注意的是圖中的虛線,表示 ThreadLocalMap 是使? ThreadLocal 的弱引?作為 Key 的,弱引?的對(duì)象在 GC 時(shí)會(huì)被回收。

ThreadLocalMap使?ThreadLocal的弱引?作為key,如果?個(gè)ThreadLocal沒(méi)有外部強(qiáng)引?來(lái)引?它,那么系統(tǒng) GC的時(shí)候,這個(gè)ThreadLocal勢(shì)必會(huì)被回收,這樣?來(lái),ThreadLocalMap中就會(huì)出現(xiàn)key為null的Entry,就沒(méi)有辦法訪問(wèn)這些key為null的Entry的value,如果當(dāng)前線程再遲遲不結(jié)束的話,這些key為null的Entry的value就會(huì)?直存在?條強(qiáng)引?鏈:Thread Ref -> Thread -> ThreaLocalMap -> Entry -> value永遠(yuǎn)?法回收,造成內(nèi)存泄漏。

3、預(yù)防辦法:在ThreadLocal的get(),set(),remove()的時(shí)候都會(huì)清除線程ThreadLocalMap?所有key為null的value。但是這些被動(dòng)的預(yù)防措施并不能保證不會(huì)內(nèi)存泄漏:

(1)使?static的ThreadLocal,延?了ThreadLocal的?命周期,可能導(dǎo)致內(nèi)存泄漏。

(2)分配使?了ThreadLocal?不再調(diào)?get(),set(),remove()?法,那么就會(huì)導(dǎo)致內(nèi)存泄漏,因?yàn)檫@塊內(nèi)存?直存在。

63 jdk8中對(duì)ConcurrentHashmap的改進(jìn)

Java 7為實(shí)現(xiàn)并?訪問(wèn),引?了Segment這?結(jié)構(gòu),實(shí)現(xiàn)了分段鎖,理論上最?并發(fā)度與Segment個(gè)數(shù)相等。

Java 8為進(jìn)?步提?并發(fā)性,摒棄了分段鎖的?案,?是直接使??個(gè)?的數(shù)組。同時(shí)為了提?哈希碰撞下的尋址性能,Java 8在鏈表?度超過(guò)?定閾值(8)時(shí)將鏈表(尋址時(shí)間復(fù)雜度為O(N))轉(zhuǎn)換為紅?樹(shù)(尋址時(shí)間復(fù)雜度為O(long(N)))。

64 concurrent包下有哪些類(lèi)?

ConcurrentHashMap、Future、FutureTask、AtomicInteger…

65 線程a,b,c,d運(yùn)?任務(wù),怎么保證當(dāng)a,b,c線程執(zhí)?完再執(zhí)?d線程?

1、CountDownLatch類(lèi)

?個(gè)同步輔助類(lèi),常?于某個(gè)條件發(fā)?后才能執(zhí)?后續(xù)進(jìn)程。給定計(jì)數(shù)初始化CountDownLatch,調(diào)?countDown()?法,在計(jì)數(shù)到達(dá)零之前,await?法?直受阻塞。

重要?法為countdown()與await();

2、join?法

將線程B加?到線程A的尾部,當(dāng)A執(zhí)?完后B才執(zhí)?。

3、notify、wait?法,Java中的喚醒與等待?法,關(guān)鍵為synchronized代碼塊,參數(shù)線程間應(yīng)相同,也常?Object作為參數(shù)。

66 ?并發(fā)系統(tǒng)如何做性能優(yōu)化?如何防?庫(kù)存超賣(mài)?

1、?并發(fā)系統(tǒng)性能優(yōu)化:優(yōu)化程序,優(yōu)化服務(wù)配置,優(yōu)化系統(tǒng)配置

盡量使?緩存,包括?戶緩存,信息緩存等,多花點(diǎn)內(nèi)存來(lái)做緩存,可以?量減少與數(shù)據(jù)庫(kù)的交互,提?性能。

?jprofiler等?具找出性能瓶頸,減少額外的開(kāi)銷(xiāo)。

優(yōu)化數(shù)據(jù)庫(kù)查詢語(yǔ)句,減少直接使?hibernate等?具的直接?成語(yǔ)句(僅耗時(shí)較?的查詢做優(yōu)化)。

優(yōu)化數(shù)據(jù)庫(kù)結(jié)構(gòu),多做索引,提?查詢效率。

統(tǒng)計(jì)的功能盡量做緩存,或按每天?統(tǒng)計(jì)或定時(shí)統(tǒng)計(jì)相關(guān)報(bào)表,避免需要時(shí)進(jìn)?統(tǒng)計(jì)的功能。

能使?靜態(tài)??的地?盡量使?,減少容器的解析(盡量將動(dòng)態(tài)內(nèi)容?成靜態(tài)html來(lái)顯示)。

解決以上問(wèn)題后,使?服務(wù)器集群來(lái)解決單臺(tái)的瓶頸問(wèn)題。

2.防?庫(kù)存超賣(mài):

悲觀鎖:在更新庫(kù)存期間加鎖,不允許其它線程修改;

數(shù)據(jù)庫(kù)鎖:select xxx for update;

分布式鎖;

樂(lè)觀鎖:使?帶版本號(hào)的更新。每個(gè)線程都可以并發(fā)修改,但在并發(fā)時(shí),只有?個(gè)線程會(huì)修改成功,其它會(huì)返回失敗。

redis watch:監(jiān)視鍵值對(duì),作?時(shí)如果事務(wù)提交exec時(shí)發(fā)現(xiàn)監(jiān)視的監(jiān)視對(duì)發(fā)?變化,事務(wù)將被取消。

消息隊(duì)列:通過(guò) FIFO 隊(duì)列,使修改庫(kù)存的操作串?化。

總結(jié):

總的來(lái)說(shuō),不能把壓?放在數(shù)據(jù)庫(kù)上,所以使? “select xxx for update” 的?式在?并發(fā)的場(chǎng)景下是不可?的。FIFO 同步隊(duì)列的?式,可以結(jié)合庫(kù)存限制隊(duì)列?,但是在庫(kù)存較多的場(chǎng)景下,?不太適?。所以相對(duì)來(lái)說(shuō),我會(huì)傾向于選擇:樂(lè)觀鎖 / 緩存鎖 / 分布式鎖的?式。


分享名稱:肝了一夜的66道并發(fā)多線程面試題,你不來(lái)個(gè)666嗎?
文章分享:http://www.dlmjj.cn/article/cooigod.html