更新時(shí)間:2020-03-19 09:45:36 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽2782次
目前接觸的多線程編程基本上都是基于java.util.concurrent這個(gè)包下的開發(fā)的,下面就以這個(gè)包來(lái)分析Java的多線程與高并發(fā)
一、分析面試題
1.在java中wait和sleep方法的不同?
最大的不同是在等待時(shí)wait會(huì)釋放鎖,而sleep一直持有鎖。Wait通常被用于線程間交互,sleep通常被用于暫停執(zhí)行。
2.創(chuàng)建多線程的三種方法
(1)繼承Thread()
(2)實(shí)現(xiàn)Runnable()接口
?。?)實(shí)現(xiàn)Callable接口
3.繼承Thread與實(shí)現(xiàn)Runnable區(qū)別
類可能只要求可執(zhí)行即可,因此繼承整個(gè)Thread類的開銷過(guò)大
4.Runnable和Callable的區(qū)別
Runnable接口中的run()方法的返回值是void;而Callable接口中的call()方法是有返回值的,和Future/FutureTask配合可以用來(lái)獲取異步執(zhí)行的結(jié)果。
5.notify作用
?。?)notify:?jiǎn)拘岩粋€(gè)正在wait當(dāng)前對(duì)象鎖的線程,并讓它拿到對(duì)象鎖
(2)notifyAll:?jiǎn)拘阉姓趙ait前對(duì)象鎖的線程
?。?)在調(diào)用wait,notify,notifyall的時(shí)候當(dāng)前線程必須獲得這個(gè)對(duì)象的鎖。
6.線程的5種狀態(tài)
7.你有哪些多線程開發(fā)良好的實(shí)踐
?。?)考慮使用線程池
?。?)優(yōu)先使用volatile保證可見性
(3)最小化同步范圍
(4)給線程命名
二、說(shuō)說(shuō)java5以后提供多線程的東西:
ExecutorServicecachedThreadPool=Executors.線程池方法
1.Java通過(guò)Executors提供四種線程池:
newCachedThreadPool創(chuàng)建一個(gè)可緩存線程池,需要就增加,不需要就減少。
newFixedThreadPool創(chuàng)建一個(gè)定長(zhǎng)線程池,可控制線程最大并發(fā)數(shù),超出的線程會(huì)在隊(duì)列中等待。
newSingleThreadExecutor創(chuàng)建一個(gè)單線程化的線程池,它只會(huì)用唯一的工作線程來(lái)執(zhí)行任務(wù),保證所有任務(wù)按照指定順序(FIFO,LIFO,優(yōu)先級(jí))執(zhí)行。
newScheduledThreadPool創(chuàng)建一個(gè)定長(zhǎng)線程池,支持定時(shí)及周期性任務(wù)執(zhí)行。(這個(gè)一般不用:一般框架就會(huì)有定時(shí)器)
2.同步工具
Semaphone(信號(hào)量)可以將任何一種容器變?yōu)橛薪缱枞萜鳎罕热绶?wù)器登錄人數(shù)過(guò)多排隊(duì)等待。
CyclicBarrier(循環(huán)屏障)他可以做出讓幾個(gè)線程都執(zhí)行到某個(gè)地方之后,才讓幾個(gè)線程同時(shí)繼續(xù)執(zhí)行。
CountDownLatch(倒計(jì)時(shí)鎖)這個(gè)類能夠使一個(gè)線程等待其他線程完成各自的工作后再執(zhí)行。
ReentrantLock(重入鎖)把鎖機(jī)制分為讀鎖、寫鎖;讓鎖更靈活
Condition用于讓指定線程等待與喚醒,按預(yù)期順序執(zhí)行,他必須和ReentrantLock重入鎖配合使用。
Callable配合Future/FutureTask獲取線程信息。
3.原子對(duì)象
AtomicInteger、AtomicLong、AtomicBoolean(Atomic則通過(guò)CAS(樂(lè)觀鎖)實(shí)現(xiàn)自動(dòng)同步)
主要是i++不是原子操作,非線程安全的,多線程訪問(wèn)的時(shí)候需要用到synchronized關(guān)鍵字保持線程同步。synchronized是悲觀鎖,在多線程競(jìng)爭(zhēng)下,加鎖、釋放鎖會(huì)導(dǎo)致比較多的上下文切換和調(diào)度延時(shí),代價(jià)就是效率低下
4.并發(fā)容器
CopyOnWriteArrayList(寫復(fù)制列表)
CopyOnWriteArraySet(寫復(fù)制集合)
底層實(shí)現(xiàn)主要是操作時(shí)復(fù)制了一份出來(lái),底層采用的是重入鎖解決并發(fā)更改問(wèn)題。
ConcurrentHashMap(分段鎖映射)
hashtable鎖住的是一整張hash表而ConcurrentHashMap底層默認(rèn)分段分成16份分別鎖住,利用樂(lè)觀鎖來(lái)操作效率問(wèn)題。
ConcurrentSkipListMap、ConcurrentSkipListSet、ConcurrentLinkedQueue、這三個(gè)都是有序的支持并發(fā)的。
具體可以看Jdk文檔
三、分布式鎖的實(shí)現(xiàn)方案
1.tair
incr和decr操作,相當(dāng)于是樂(lè)觀鎖
2.Redis/memcache
setNx命令
3.Zookeeper
充分利用watcher機(jī)制,創(chuàng)建臨時(shí)結(jié)點(diǎn),誰(shuí)創(chuàng)建成功,誰(shuí)就獲得當(dāng)前的鎖
4.數(shù)據(jù)庫(kù):利用數(shù)據(jù)庫(kù)的行鎖
//加鎖SQL
updatetrade_basesetstatus=1wheretrade_no=“XXX”andstatus=0;
//解鎖SQL
updatetrade_basesetstatus=0wheretrade_no=“XXX”andstatus=1;
注意trade_base表上一要有trade_no的列的唯一索引
當(dāng)然具體用那種分布鎖,還需要結(jié)合業(yè)務(wù)自身的需要,一般來(lái)說(shuō),在并發(fā)量不是別大,數(shù)據(jù)庫(kù)完全可以扛得住的情況下,用數(shù)據(jù)庫(kù)實(shí)現(xiàn)分布鎖最快,最方便,而且性能的損失也非常地小;
當(dāng)然現(xiàn)在很多場(chǎng)景下,都是分庫(kù)分表,并且加鎖和解鎖分別都只影響一行,對(duì)數(shù)據(jù)庫(kù)來(lái)說(shuō),加鎖和解鎖的sql也是非常輕量的sql操作,因此在性能損失上不用過(guò)多的擔(dān)心。
以上就是動(dòng)力節(jié)點(diǎn)Java培訓(xùn)機(jī)構(gòu)小編介紹的“Java多線程開發(fā)視頻教程”的內(nèi)容,希望對(duì)大家有幫助,如有疑問(wèn),請(qǐng)?jiān)诰€咨詢,有專業(yè)老師隨時(shí)為你服務(wù)。
相關(guān)閱讀
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
有基礎(chǔ) 直達(dá)就業(yè)
業(yè)余時(shí)間 高薪轉(zhuǎn)行
工作1~3年,加薪神器
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問(wèn)老師會(huì)電話與您溝通安排學(xué)習(xí)
初級(jí) 202925
初級(jí) 203221
初級(jí) 202629
初級(jí) 203743