?
1、多線程并發(fā)
1)多線程中 synchronized 鎖升級(jí)的原理是什么?
synchronized 鎖升級(jí)原理:在鎖對(duì)象的對(duì)象頭里面有一個(gè) threadid 字段,在第一次訪問(wèn)的時(shí)候 threadid 為空,jvm 讓其持有偏向鎖,并將 threadid 設(shè)置為其線程 id,再次進(jìn)入的時(shí)候會(huì)先判斷 threadid 是否與其線程 id 一致,如果一致則可以直接使用此對(duì)象,如果不一致,則升級(jí)偏向鎖為 輕量級(jí)鎖,通過(guò)自旋循環(huán)一定次數(shù)來(lái)獲取鎖,執(zhí)行一定次數(shù)之后,如果還沒(méi)有正常獲取到要使用的 對(duì)象,此時(shí)就會(huì)把鎖從輕量級(jí)升級(jí)為重量級(jí)鎖,此過(guò)程就構(gòu)成了 synchronized 鎖的升級(jí)。 鎖的升級(jí)的目的:鎖升級(jí)是為了減低了鎖帶來(lái)的性能消耗。在 Java 6 之后優(yōu)化 synchronized 的實(shí)現(xiàn)方 式,使用了偏向鎖升級(jí)為輕量級(jí)鎖再升級(jí)到重量級(jí)鎖的方式,從而減低了鎖帶來(lái)的性能消耗。
偏向鎖,顧名思義,它會(huì)偏向于第一個(gè)訪問(wèn)鎖的線程,如果在運(yùn)行過(guò)程中,同步鎖只有一個(gè)線程訪 問(wèn),不存在多線程爭(zhēng)用的情況,則線程是不需要觸發(fā)同步的,減少加鎖/解鎖的一些CAS操作(比 如等待隊(duì)列的一些CAS操作),這種情況下,就會(huì)給線程加一個(gè)偏向鎖。 如果在運(yùn)行過(guò)程中,遇 到了其他線程搶占鎖,則持有偏向鎖的線程會(huì)被掛起,JVM會(huì)消除它身上的偏向鎖,將鎖恢復(fù)到標(biāo) 準(zhǔn)的輕量級(jí)鎖。
輕量級(jí)鎖是由偏向所升級(jí)來(lái)的,偏向鎖運(yùn)行在一個(gè)線程進(jìn)入同步塊的情況下,當(dāng)?shù)诙€(gè)線程加入鎖 爭(zhēng)用的時(shí)候,輕量級(jí)鎖就會(huì)升級(jí)為重量級(jí)鎖;
重量級(jí)鎖是synchronized ,是 Java 虛擬機(jī)中最為基礎(chǔ)的鎖實(shí)現(xiàn)。在這種狀態(tài)下,Java 虛擬機(jī)會(huì)阻 塞加鎖失敗的線程,并且在目標(biāo)鎖被釋放的時(shí)候,喚醒這些線程。
2、線程池有什么優(yōu)點(diǎn)?
降低資源消耗:重用存在的線程,減少對(duì)象創(chuàng)建銷(xiāo)毀的開(kāi)銷(xiāo)。
提高響應(yīng)速度:可有效的控制最大并發(fā)線程數(shù),提高系統(tǒng)資源的使用率,同時(shí)避免過(guò)多資源競(jìng)爭(zhēng), 避免堵塞。當(dāng)任務(wù)到達(dá)時(shí),任務(wù)可以不需要的等到線程創(chuàng)建就能立即執(zhí)行。
提高線程的可管理性:線程是稀缺資源,如果無(wú)限制的創(chuàng)建,不僅會(huì)消耗系統(tǒng)資源,還會(huì)降低系統(tǒng) 的穩(wěn)定性,使用線程池可以進(jìn)行統(tǒng)一的分配,調(diào)優(yōu)和監(jiān)控。
附加功能:提供定時(shí)執(zhí)行、定期執(zhí)行、單線程、并發(fā)數(shù)控制等功能。
3、ThreadPoolExecutor飽和策略有哪些?
如果當(dāng)前同時(shí)運(yùn)行的線程數(shù)量達(dá)到最大線程數(shù)量并且隊(duì)列也已經(jīng)被放滿了任時(shí),ThreadPoolTaskExecutor 定 義一些策略:
ThreadPoolExecutor.AbortPolicy:拋出 RejectedExecutionException來(lái)拒絕新任務(wù)的處理。
ThreadPoolExecutor.CallerRunsPolicy:調(diào)用執(zhí)行自己的線程運(yùn)行任務(wù)。您不會(huì)任務(wù)請(qǐng)求。但是 這種策略會(huì)降低對(duì)于新任務(wù)提交速度,影響程序的整體性能。另外,這個(gè)策略喜歡增加隊(duì)列容量。 如果您的應(yīng)用程序可以承受此延遲并且你不能任務(wù)丟棄任何一個(gè)任務(wù)請(qǐng)求的話,你可以選擇這個(gè)策 略
(當(dāng)前線程調(diào)用線程池處理多線程任務(wù),線程池隊(duì)列滿了,那么就會(huì)用當(dāng)前調(diào)用多線程的線程,即用戶線程來(lái)執(zhí)行當(dāng)前需要執(zhí)行的多線程任務(wù)===影響性能,但是不會(huì)丟失任務(wù))
ThreadPoolExecutor.DiscardPolicy:不處理新任務(wù),直接丟棄掉。 ThreadPoolExecutor.DiscardOldestPolicy: 此策略將丟棄最早的未處理的任務(wù)請(qǐng)求。
4、ThreadPoolExecutor線程池的執(zhí)行原理?
5、如何合理分配線程池大小?
要合理的分配線程池的大小要根據(jù)實(shí)際情況來(lái)定,
簡(jiǎn)單的來(lái)說(shuō)的話就是根據(jù)CPU密集和IO密集來(lái) 分配
什么是CPU密集 CPU密集的意思是該任務(wù)需要大量的運(yùn)算,而沒(méi)有阻塞,CPU一直全速運(yùn)行。 CPU密集任務(wù)只有在真正的多核CPU上才可能得到加速(通過(guò)多線程),而在單核CPU上,無(wú)論你開(kāi) 幾個(gè)模擬的多線程,該任務(wù)都不可能得到加速,因?yàn)镃PU總的運(yùn)算能力就那樣。
什么是IO密集 IO密集型,即該任務(wù)需要大量的IO,即大量的阻塞。在單線程上運(yùn)行IO密集型的任務(wù)會(huì)導(dǎo)致浪費(fèi) 大量的CPU運(yùn)算能力浪費(fèi)在等待。所以在IO密集型任務(wù)中使用多線程可以大大的加速程序運(yùn)行, 即時(shí)在單核CPU上,這種加速主要就是利用了被浪費(fèi)掉的阻塞時(shí)間。
分配CPU和IO密集: 1. CPU密集型時(shí),任務(wù)可以少配置線程數(shù),大概和機(jī)器的cpu核數(shù)相當(dāng),這樣可以使得每個(gè)線程都在 執(zhí)行任務(wù) 2. IO密集型時(shí),大部分線程都阻塞,故需要多配置線程數(shù),2*cpu核數(shù) 精確來(lái)說(shuō)的話的話:
從以下幾個(gè)角度分析任務(wù)的特性: 任務(wù)的性質(zhì):CPU密集型任務(wù)、IO密集型任務(wù)、混合型任務(wù)。 任務(wù)的優(yōu)先級(jí):高、中、低。 任務(wù)的執(zhí)行時(shí)間:長(zhǎng)、中、短。 任務(wù)的依賴(lài)性:是否依賴(lài)其他系統(tǒng)資源,如數(shù)據(jù)庫(kù)連接等。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-455424.html
可以得出一個(gè)結(jié)論: 線程等待時(shí)間比CPU執(zhí)行時(shí)間比例越高,需要越多線程。 線程CPU執(zhí)行時(shí)間比等待時(shí)間比例越高,需要越少線程。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-455424.html
到了這里,關(guān)于Java -并發(fā)(多線程)-Interview面試題收集的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!