并發(fā)知識點(diǎn)總結(jié)
1、JAVA內(nèi)存模型(注意與JVM內(nèi)存模型的區(qū)別)
內(nèi)存模型:定義一組規(guī)范,圍繞可見性、原子性、有序性定義變量的訪問方式,屏蔽軟硬件差異達(dá)到內(nèi)存一致性效果。
2、volatile關(guān)鍵字
可見性:內(nèi)存屏障保證寫操作立刻刷新緩存,讀操作要從內(nèi)存讀取最新值到工作內(nèi)存
禁止指令重排:(針對普通無鎖的全局變量)插入內(nèi)存屏障,保證先于屏障的指令先執(zhí)行,后于內(nèi)存屏障的后執(zhí)行
3、原子性、可見性、有序性
原子性:內(nèi)存模型的原子性變量操作和lock、unluck,提供給程序原使用的是synchronized(字節(jié)碼指令monitorenter和monitorexit)
可見性:新值能夠立刻同步到主存,讀取前立刻從主存刷新,提供給程序員使用的是volatile,synchronized,final
有序性:線程內(nèi)有序,線程間無序。通過,先行發(fā)生原則和,volatile,synchronized
我們必須要清楚,定義內(nèi)存模型是為了解決內(nèi)存一致性問題,即并發(fā)情況下工作內(nèi)存到主存的問題,這在程序員層面是不可見的。換句話說,就是內(nèi)存模型保證了原子性、可見性、有序性,而我們使用的關(guān)鍵字則是內(nèi)存模型提供給上層程序員的一種控制內(nèi)存的手段。我們有了內(nèi)存一致性,還要進(jìn)行同步控制的原因是:內(nèi)存一致性解決的是內(nèi)存問題,并發(fā)控制是保證程序的正確性。
4、創(chuàng)建線程的三種方式
- 繼承Thread重寫run()方法
- 實現(xiàn)Runnable接口,實現(xiàn)run()方法
- 實現(xiàn)Callable接口,實現(xiàn)call()方法
Callable泛型接口的call方法有返回值,submit提交返回一個異步執(zhí)行的結(jié)果Future。
5、線程有哪些狀態(tài)
- New:新建狀態(tài),還未啟動
- Runnable:Java中Runnable包括運(yùn)行和就緒兩種狀態(tài)由yield切換
- Blocked:只有synchronized關(guān)鍵字可以使線程進(jìn)入阻塞狀態(tài)
- Wait:無限等待
- Time—Wait:有限等待
- Terminate:終止
6、什么是守護(hù)線程
守護(hù)線程就是后臺線程,所有的非后臺線程結(jié)束虛擬機(jī)退出后臺線程自動結(jié)束,后臺線程的子線程是后臺線程。
7、run()與start()的區(qū)別
run():就是一個普通的方法
start():啟動一個線程去驅(qū)動任務(wù),并馬上返回。
8、yield,sleep,join,wait區(qū)別
yield:將當(dāng)前線程從運(yùn)行狀態(tài)切換到就緒狀態(tài),讓給同優(yōu)先級的線程運(yùn)行的機(jī)會
sleep:當(dāng)前線程等待,但是不釋放鎖
join:等待子線程執(zhí)行完畢,子線程即調(diào)用join的線程
wait:只能用在同步控制塊中,釋放鎖,并且wait要重新獲得獲得的鎖才能真正喚醒;作用是線程協(xié)作,一般放在while循環(huán)中,等待條件發(fā)生變化
9、notify與notifyAll
①notify喚醒一個線程,notifyAll喚醒等待同一個鎖的所有線程
②notify要保證喚醒的線程等待相同的條件,所以notifyAll更加安全
③notify比notifyAll更加優(yōu)化
10、synchronized底層實現(xiàn)原理
內(nèi)存模型層面:lock、unlock
字節(jié)碼指令:monitorenter,monitorexit
11、synchronized與volatile
①volatile修飾變量,synchronized修飾同步塊
②volatile不能保證原子性,synchronized可以
③volatile不阻塞synchronized阻塞
12、synchronized與Lock與ReentrantLock
Lock是ReentrantLock的接口
①synchronized是內(nèi)置關(guān)鍵字,ReentrantLock是java類
②ReentrantLock可以實現(xiàn)公平鎖,默認(rèn)是非公平鎖
③ReentrantLock等待可中斷,線程等待久了可以放棄等待
④ReentrantLock由park()阻塞原語使線程進(jìn)入等待狀態(tài),synchronized使得線程進(jìn)入阻塞狀態(tài)
⑤ReentrantLock可以綁定多個條件,進(jìn)行更加細(xì)致的同步控制。
13、實現(xiàn)線程安全的三種方式
- 阻塞同步,互斥同步(即加鎖)
- 非阻塞同步,CAS(原子類)
- 線程本地存儲:為每個線程分配一個共享變量的副本,通常都用static存儲ThreadLocal對象,應(yīng)用場景,數(shù)據(jù)庫連接等線程私有對象。
14、CAS操作與atomic原理
compareAndSwap(o1,o2,o3)
以對變量i加1舉例,o1是第一次讀取i的值,o2是做CAS操作時讀取i的值,o3是i+1的值,做CAS操作時比較o1與o2,若兩者相等說明沒有沖突可以更新i值,若不相等說明有沖突不能更新i值,采取補(bǔ)償措施不斷重試。
這里面有個邏輯漏洞:ABA問題,就是i的值從A改到B,又從B改到A而無法察覺,可以用AtomicStampedReference類通過版本值來解決,或者用鎖。
這類比較雞肋,一般情況下ABA問題不會影響程序的正確性,解決ABA問題鎖又更加高效。
15、CountDownLatch、CyclicBarrier、Semaphore
CountDownLatch:一個鎖存器,等到計數(shù)器為0之前,await方法一直等待,無法重置。
CyclicBarrier:循環(huán)屏障,參與者數(shù)目達(dá)到指定值之前(即await方法調(diào)用次數(shù)到達(dá)指定值),await方法一直等待,可以重置。
Semaphore:信號量設(shè)置n個許可,在許可可用前,acquire()等待。
16、并發(fā)集合
CopyOnWriteArrayList相當(dāng)于線程安全的ArrayList
CopyOnWriteArraySet相當(dāng)于線程安全的HashSet
ConcurrentHashMap相當(dāng)于線程安全的HashMap
ConcurrentSkipListMap相當(dāng)于線程安全的TreeMap
ConcurrentSkipListSet相當(dāng)于線程安全的TreeSet
ArrayBlockingQueue是數(shù)組實現(xiàn)的線程安全的有界的阻塞隊列
LinkedBlockingQueue是單向鏈表實現(xiàn)的(可指定大小)阻塞隊列
ConcurrentLinkedQueue是單向鏈表實現(xiàn)的無界隊列
17、ConcurrentHashMap JDK1.7與JDK1.8的區(qū)別
JDK1.7:將哈希表分段,即由很多segment片段組成,每一段就是一個可重入的互斥鎖,HashTable鎖全表
JDK1.8:使用CAS+synchronized實現(xiàn)線程安全,鎖的粒度變成了節(jié)點(diǎn),如HashMap節(jié)點(diǎn)超過8就會樹化
18、線程池
線程池的原理:在池中維護(hù)一定數(shù)量的線程驅(qū)動任務(wù),線程池幫助管理線程以免頻繁創(chuàng)建回收線程。
19、線程池的狀態(tài)

①Running狀態(tài)調(diào)用shutdown()進(jìn)入ShutDown狀態(tài):此時線程池不接受新任務(wù),但仍舊處理已提交任務(wù),處理完任務(wù)進(jìn)入Tidying狀態(tài)
②Running狀態(tài)調(diào)用shutdownNow()進(jìn)入STOP狀態(tài):此時線程池不接受新任務(wù),不處理就任務(wù),正在運(yùn)行的任務(wù)中斷,線程池任務(wù)為0進(jìn)入Tidying狀態(tài)
③Tidying狀態(tài)執(zhí)行鉤子函數(shù)terminate()進(jìn)入Terminated狀態(tài)
20、線程池的相關(guān)參數(shù)
corepoolsize與maxpoolsize,前者是核心池大小,后者是最大池大小。池中線程數(shù)小于corepoolsize創(chuàng)建新線程處理任務(wù),池中線程數(shù)多于corepoolsize但是小于maxpoolsize阻塞隊列滿在創(chuàng)建新線程。
keepalivetime:允許空閑線程存活的時間
21、排隊的三種策略
①直接提交:阻塞隊列設(shè)為0,maxpoolsize設(shè)置無限大。
②無界隊列:一般corepoolsize=maxpoolsize,線程池維護(hù)固定數(shù)量線程。
③有界隊列:線程池大小與隊列大小難以權(quán)衡。
22、四種線程池類型
SingelThreadPool:線程池維護(hù)單個線程
FixedThreadPool:線程池維護(hù)固定數(shù)量線程
ScheduledThreadPool:線程池維護(hù)固定數(shù)量線程,線程設(shè)置在一定時延后進(jìn)行
CacheThreadPool:線程池可以根據(jù)需要創(chuàng)建線程,空閑線程60秒后回收

浙公網(wǎng)安備 33010602011771號