經(jīng)典Java面試題的答案——多線程

大家好篡诽,我是九神。這是互聯(lián)網(wǎng)技術(shù)崗的分享專題墓塌,廢話少說(shuō),進(jìn)入正題:

35.并行和并發(fā)有什么區(qū)別奥额?

并發(fā)(concurrency):指在同一時(shí)刻只能有一條指令執(zhí)行,但多個(gè)進(jìn)程指令被快速的輪換執(zhí)行访诱,使得在宏觀上具有多個(gè)進(jìn)程同時(shí)執(zhí)行的效果垫挨,但在微觀上并不是同時(shí)執(zhí)行的,只是把時(shí)間分成若干端触菜,使多個(gè)進(jìn)程快速交替的執(zhí)行九榔。

并行(parallellism):指在同一時(shí)刻,有多條指令在多個(gè)處理器上同時(shí)執(zhí)行涡相。

直白的:并發(fā)是交替執(zhí)行哲泊,并行是同時(shí)執(zhí)行。

36.線程和進(jìn)程的區(qū)別催蝗?

進(jìn)程是程序運(yùn)行和資源分配的基本單位切威,一個(gè)程序至少有一個(gè)進(jìn)程,一個(gè)進(jìn)程至少有一個(gè)線程丙号。

進(jìn)程在執(zhí)行過(guò)程中擁有獨(dú)立的內(nèi)存單元先朦,而多個(gè)線程共享內(nèi)存資源缰冤,減少切換次數(shù),從而效率更高喳魏。

線程是進(jìn)程的一個(gè)實(shí)體棉浸,是cpu調(diào)度和分派的基本單位,是比程序更小的能獨(dú)立運(yùn)行的基本單位刺彩。同一進(jìn)程中的多個(gè)線程之間可以并發(fā)執(zhí)行迷郑。

37.守護(hù)線程是什么?

java里線程分2種:

1创倔、守護(hù)線程(即daemon thread)嗡害,是個(gè)服務(wù)線程,準(zhǔn)確地來(lái)說(shuō)就是服務(wù)其他的線程三幻。比如垃圾回收線程就漾,就是最典型的守護(hù)線程。

2念搬、用戶線程抑堡,就是應(yīng)用程序里的自定義線程。

守護(hù)線程的意義

當(dāng)主線程結(jié)束時(shí)朗徊,結(jié)束其余的子線程(守護(hù)線程)自動(dòng)關(guān)閉首妖,就免去了還要繼續(xù)關(guān)閉子線程的麻煩。

如:Java垃圾回收線程就是一個(gè)典型的守護(hù)線程爷恳;內(nèi)存資源或者線程的管理有缆,但是非守護(hù)線程也可以。

38.創(chuàng)建線程有哪幾種方式温亲?

1棚壁、繼承Thread類創(chuàng)建線程類

  • 定義Thread類的子類,并重寫該類的run方法栈虚,該run方法的方法體就代表了線程要完成的任務(wù)袖外。因此把run()方法稱為執(zhí)行體。

  • 創(chuàng)建Thread子類的實(shí)例魂务,即創(chuàng)建了線程對(duì)象曼验。

  • 調(diào)用線程對(duì)象的start()方法來(lái)啟動(dòng)該線程。

2粘姜、通過(guò)Runnable接口創(chuàng)建線程類

  • 定義runnable接口的實(shí)現(xiàn)類鬓照,并重寫該接口的run()方法,該run()方法的方法體同樣是該線程的線程執(zhí)行體孤紧。

  • 創(chuàng)建 Runnable實(shí)現(xiàn)類的實(shí)例豺裆,并依此實(shí)例作為Thread的target來(lái)創(chuàng)建Thread對(duì)象,該Thread對(duì)象才是真正的線程對(duì)象号显。

  • 調(diào)用線程對(duì)象的start()方法來(lái)啟動(dòng)該線程留储。

3翼抠、通過(guò)Callable和Future創(chuàng)建線程

  • 創(chuàng)建Callable接口的實(shí)現(xiàn)類,并實(shí)現(xiàn)call()方法获讳,該call()方法將作為線程執(zhí)行體阴颖,并且有返回值。

  • 創(chuàng)建Callable實(shí)現(xiàn)類的實(shí)例丐膝,使用FutureTask類來(lái)包裝Callable對(duì)象量愧,該FutureTask對(duì)象封裝了該Callable對(duì)象的call()方法的返回值。

  • 使用FutureTask對(duì)象作為Thread對(duì)象的target創(chuàng)建并啟動(dòng)新線程帅矗。

  • 調(diào)用FutureTask對(duì)象的get()方法來(lái)獲得子線程執(zhí)行結(jié)束后的返回值偎肃。

39.說(shuō)一下 runnable 和 callable 有什么區(qū)別?

Runnable接口中的run()方法的返回值是void浑此,它做的事情只是純粹地去執(zhí)行run()方法中的代碼而已累颂;

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

40.線程有哪些狀態(tài)?

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

  • 創(chuàng)建狀態(tài)奋隶。在生成線程對(duì)象擂送,并沒有調(diào)用該對(duì)象的start方法,這是線程處于創(chuàng)建狀態(tài)唯欣。

  • 就緒狀態(tài)嘹吨。當(dāng)調(diào)用了線程對(duì)象的start方法之后,該線程就進(jìn)入了就緒狀態(tài)黍聂,但是此時(shí)線程調(diào)度程序還沒有把該線程設(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)她按,開始運(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)死亡的線程,無(wú)法再使用start方法令其進(jìn)入就緒

41.sleep() 和 wait() 有什么區(qū)別狸剃?

sleep():方法是線程類(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ī)鎖沒有被釋放膝擂,其他線程依然無(wú)法訪問這個(gè)對(duì)象。

wait():wait()是Object類的方法隙弛,當(dāng)一個(gè)線程執(zhí)行到wait方法時(shí)架馋,它就進(jìn)入到一個(gè)和該對(duì)象相關(guān)的等待池,同時(shí)釋放對(duì)象的機(jī)鎖全闷,使得其他線程能夠訪問叉寂,可以通過(guò)notify,notifyAll方法來(lái)喚醒等待的線程

42.notify()和 notifyAll()有什么區(qū)別总珠?

  • 如果線程調(diào)用了對(duì)象的 wait()方法屏鳍,那么線程便會(huì)處于該對(duì)象的等待池中,等待池中的線程不會(huì)去競(jìng)爭(zhēng)該對(duì)象的鎖局服。

  • 當(dāng)有線程調(diào)用了對(duì)象的 notifyAll()方法(喚醒所有 wait 線程)或 notify()方法(只隨機(jī)喚醒一個(gè) wait 線程)钓瞭,被喚醒的的線程便會(huì)進(jìn)入該對(duì)象的鎖池中,鎖池中的線程會(huì)去競(jìng)爭(zhēng)該對(duì)象鎖淫奔。也就是說(shuō)山涡,調(diào)用了notify后只要一個(gè)線程會(huì)由等待池進(jìn)入鎖池,而notifyAll會(huì)將該對(duì)象等待池內(nèi)的所有線程移動(dòng)到鎖池中,等待鎖競(jìng)爭(zhēng)鸭丛。

  • 優(yōu)先級(jí)高的線程競(jìng)爭(zhēng)到對(duì)象鎖的概率大竞穷,假若某線程沒有競(jìng)爭(zhēng)到該對(duì)象鎖,它還會(huì)留在鎖池中鳞溉,唯有線程再次調(diào)用 wait()方法瘾带,它才會(huì)重新回到等待池中。而競(jìng)爭(zhēng)到對(duì)象鎖的線程則繼續(xù)往下執(zhí)行穿挨,直到執(zhí)行完了 synchronized 代碼塊月弛,它會(huì)釋放掉該對(duì)象鎖,這時(shí)鎖池中的線程會(huì)繼續(xù)競(jìng)爭(zhēng)該對(duì)象鎖科盛。

43.線程的 run()和 start()有什么區(qū)別帽衙?

每個(gè)線程都是通過(guò)某個(gè)特定Thread對(duì)象所對(duì)應(yīng)的方法run()來(lái)完成其操作的,方法run()稱為線程體贞绵。通過(guò)調(diào)用Thread類的start()方法來(lái)啟動(dòng)一個(gè)線程厉萝。

start()方法來(lái)啟動(dòng)一個(gè)線程,真正實(shí)現(xiàn)了多線程運(yùn)行榨崩。這時(shí)無(wú)需等待run方法體代碼執(zhí)行完畢谴垫,可以直接繼續(xù)執(zhí)行下面的代碼;這時(shí)此線程是處于就緒狀態(tài)母蛛, 并沒有運(yùn)行翩剪。然后通過(guò)此Thread類調(diào)用方法run()來(lái)完成其運(yùn)行狀態(tài), 這里方法run()稱為線程體彩郊,它包含了要執(zhí)行的這個(gè)線程的內(nèi)容前弯, Run方法運(yùn)行結(jié)束, 此線程終止秫逝。然后CPU再調(diào)度其它線程恕出。

run()方法是在本線程里的,只是線程里的一個(gè)函數(shù),而不是多線程的违帆。如果直接調(diào)用run(),其實(shí)就相當(dāng)于是調(diào)用了一個(gè)普通函數(shù)而已浙巫,直接待用run()方法必須等待run()方法執(zhí)行完畢才能執(zhí)行下面的代碼,所以執(zhí)行路徑還是只有一條刷后,根本就沒有線程的特征的畴,所以在多線程執(zhí)行時(shí)要使用start()方法而不是run()方法。

44.創(chuàng)建線程池有哪幾種方式尝胆?

1丧裁、newFixedThreadPool(int nThreads)

創(chuàng)建一個(gè)固定長(zhǎng)度的線程池,每當(dāng)提交一個(gè)任務(wù)就創(chuàng)建一個(gè)線程班巩,直到達(dá)到線程池的最大數(shù)量渣慕,這時(shí)線程規(guī)模將不再變化,當(dāng)線程發(fā)生未預(yù)期的錯(cuò)誤而結(jié)束時(shí)抱慌,線程池會(huì)補(bǔ)充一個(gè)新的線程逊桦。

2、newCachedThreadPool()

創(chuàng)建一個(gè)可緩存的線程池抑进,如果線程池的規(guī)模超過(guò)了處理需求强经,將自動(dòng)回收空閑線程,而當(dāng)需求增加時(shí)寺渗,則可以自動(dòng)添加新線程匿情,線程池的規(guī)模不存在任何限制。

3信殊、newSingleThreadExecutor()

這是一個(gè)單線程的Executor炬称,它創(chuàng)建單個(gè)工作線程來(lái)執(zhí)行任務(wù),如果這個(gè)線程異常結(jié)束涡拘,會(huì)創(chuàng)建一個(gè)新的來(lái)替代它玲躯;它的特點(diǎn)是能確保依照任務(wù)在隊(duì)列中的順序來(lái)串行執(zhí)行。

4鳄乏、newScheduledThreadPool(int corePoolSize)

創(chuàng)建了一個(gè)固定長(zhǎng)度的線程池跷车,而且以延遲或定時(shí)的方式來(lái)執(zhí)行任務(wù),類似于Timer橱野。

45.線程池都有哪些狀態(tài)朽缴?

線程池有5種狀態(tài):Running、ShutDown水援、Stop密强、Tidying、Terminated裹唆。

線程池各個(gè)狀態(tài)切換框架圖:

img

46.線程池中 submit()和 execute()方法有什么區(qū)別誓斥?

  • 接收的參數(shù)不一樣

  • submit有返回值,而execute沒有

  • submit方便Exception處理

47.在 java 程序中怎么保證多線程的運(yùn)行安全许帐?

線程安全在三個(gè)方面體現(xiàn):

  • 原子性:提供互斥訪問劳坑,同一時(shí)刻只能有一個(gè)線程對(duì)數(shù)據(jù)進(jìn)行操作,(atomic,synchronized)成畦;

  • 可見性:一個(gè)線程對(duì)主內(nèi)存的修改可以及時(shí)地被其他線程看到距芬,(synchronized,volatile);

  • 有序性:一個(gè)線程觀察其他線程中的指令執(zhí)行順序循帐,由于指令重排序框仔,該觀察結(jié)果一般雜亂無(wú)序,(happens-before原則)拄养。

48.多線程鎖的升級(jí)原理是什么离斩?

鎖的級(jí)別:無(wú)鎖->偏向鎖->輕量級(jí)鎖->重量級(jí)鎖

鎖分級(jí)別原因:沒有優(yōu)化前银舱,sychroniezed是重量級(jí)鎖(悲觀鎖),使用wait跛梗、notify寻馏、notifyAll來(lái)切換線程狀態(tài)非常消耗系統(tǒng)資源,線程的掛起和喚醒間隔很短暫核偿,這樣很浪費(fèi)資源诚欠,影響性能。所以JVM對(duì)sychronized關(guān)鍵字進(jìn)行了優(yōu)化漾岳,把鎖分為無(wú)鎖轰绵、偏向鎖、輕量級(jí)鎖尼荆、重量級(jí)鎖左腔。當(dāng)JVM檢測(cè)到不同的競(jìng)爭(zhēng)狀態(tài)時(shí),就會(huì)根據(jù)需要自動(dòng)切換到合適的鎖捅儒,這種切換就是鎖的升級(jí)翔悠。

升級(jí)是不可逆的,也就是說(shuō)只能從低到高野芒,也就是偏向-->輕量級(jí)-->重量級(jí)蓄愁,不能夠降級(jí)

以下是五種鎖(醬油君評(píng):非必要回答,答上來(lái)加分):

一狞悲、無(wú)鎖

沒有對(duì)資源進(jìn)行鎖定撮抓,所有的線程都能訪問并修改同一個(gè)資源,但同時(shí)只有一個(gè)線程能修改成功摇锋,其它修改失敗的線程會(huì)不斷重試直到修改成功丹拯。

二、偏向鎖

對(duì)象的代碼一直被同一線程執(zhí)行荸恕,不存在多個(gè)線程競(jìng)爭(zhēng)乖酬,該線程在后續(xù)執(zhí)行中自動(dòng)獲取鎖,降低獲取鎖帶來(lái)的性能開銷融求。偏向鎖咬像,指的是偏向第一個(gè)加鎖線程,該線程是不會(huì)主動(dòng)釋放偏向鎖的生宛,只有當(dāng)其他線程嘗試競(jìng)爭(zhēng)偏向鎖才會(huì)被釋放县昂。

偏向鎖的撤銷,需要在某個(gè)時(shí)間點(diǎn)上沒有字節(jié)碼正在執(zhí)行時(shí)陷舅,先暫停偏向鎖的線程倒彰,然后判斷鎖對(duì)象是否處于被鎖定狀態(tài),如果線程不處于活動(dòng)狀態(tài)莱睁,則將對(duì)象頭設(shè)置成無(wú)鎖狀態(tài)待讳,并撤銷偏向鎖芒澜。

如果線程處于活動(dòng)狀態(tài),升級(jí)為輕量級(jí)鎖的狀態(tài)创淡。

三撰糠、輕量級(jí)鎖

輕量級(jí)鎖是指當(dāng)鎖是偏向鎖的時(shí)候,被第二個(gè)線程B訪問辩昆,此時(shí)偏向鎖就會(huì)升級(jí)為輕量級(jí)鎖,線程B會(huì)通過(guò)自旋的形式嘗試獲取鎖旨袒,線程不會(huì)阻塞汁针,從未提升性能。

當(dāng)前只有一個(gè)等待線程砚尽,則該線程將通過(guò)自旋進(jìn)行等待施无。但是當(dāng)自旋超過(guò)一定次數(shù)時(shí),輕量級(jí)鎖邊會(huì)升級(jí)為重量級(jí)鎖必孤,當(dāng)一個(gè)線程已持有鎖猾骡,另一個(gè)線程在自旋,而此時(shí)第三個(gè)線程來(lái)訪時(shí)敷搪,輕量級(jí)鎖也會(huì)升級(jí)為重量級(jí)鎖兴想。

注:自旋是什么?

自旋(spinlock)是指當(dāng)一個(gè)線程獲取鎖的時(shí)候赡勘,如果鎖已經(jīng)被其它線程獲取嫂便,那么該線程將循環(huán)等待,然后不斷的判斷鎖是否能夠被成功獲取闸与,直到獲取到鎖才會(huì)退出循環(huán)毙替。

四、重量級(jí)鎖

指當(dāng)有一個(gè)線程獲取鎖之后践樱,其余所有等待獲取該鎖的線程都會(huì)處于阻塞狀態(tài)厂画。

重量級(jí)鎖通過(guò)對(duì)象內(nèi)部的監(jiān)聽器(monitor)實(shí)現(xiàn),而其中monitor的本質(zhì)是依賴于底層操作系統(tǒng)的Mutex Lock實(shí)現(xiàn)拷邢,操作系統(tǒng)實(shí)現(xiàn)線程之間的切換需要從用戶態(tài)切換到內(nèi)核態(tài)袱院,切換成本非常高。

鎖升級(jí)的圖示過(guò)程:

img

49.什么是死鎖瞭稼?

死鎖是指兩個(gè)或兩個(gè)以上的進(jìn)程在執(zhí)行過(guò)程中坑填,由于競(jìng)爭(zhēng)資源或者由于彼此通信而造成的一種阻塞的現(xiàn)象,若無(wú)外力作用弛姜,它們都將無(wú)法推進(jìn)下去脐瑰。此時(shí)稱系統(tǒng)處于死鎖狀態(tài)或系統(tǒng)產(chǎn)生了死鎖,這些永遠(yuǎn)在互相等待的進(jìn)程稱為死鎖進(jìn)程廷臼。是操作系統(tǒng)層面的一個(gè)錯(cuò)誤苍在,是進(jìn)程死鎖的簡(jiǎn)稱绝页,最早在 1965 年由 Dijkstra 在研究銀行家算法時(shí)提出的,它是計(jì)算機(jī)操作系統(tǒng)乃至整個(gè)并發(fā)程序設(shè)計(jì)領(lǐng)域最難處理的問題之一寂恬。

50.怎么防止死鎖续誉?

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

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

  • 請(qǐng)求和保持條件:進(jìn)程獲得一定的資源之后,又對(duì)其他資源發(fā)出請(qǐng)求牙咏,但是該資源可能被其他進(jìn)程占有臼隔,此事請(qǐng)求阻塞,但又對(duì)自己獲得的資源保持不放

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

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

這四個(gè)條件是死鎖的必要條件氨淌,只要系統(tǒng)發(fā)生死鎖,這些條件必然成立伊磺,而只要上述條件之 一不滿足盛正,就不會(huì)發(fā)生死鎖。

理解了死鎖的原因屑埋,尤其是產(chǎn)生死鎖的四個(gè)必要條件蛮艰,就可以最大可能地避免、預(yù)防和 解除死鎖雀彼。

所以壤蚜,在系統(tǒng)設(shè)計(jì)、進(jìn)程調(diào)度等方面注意如何不讓這四個(gè)必要條件成立徊哑,如何確 定資源的合理分配算法袜刷,避免進(jìn)程永久占據(jù)系統(tǒng)資源。

此外莺丑,也要防止進(jìn)程在處于等待狀態(tài)的情況下占用資源著蟹。因此,對(duì)資源的分配要給予合理的規(guī)劃梢莽。

51.ThreadLocal 是什么萧豆?有哪些使用場(chǎng)景?

線程局部變量是局限于線程內(nèi)部的變量昏名,屬于線程自身所有涮雷,不在多個(gè)線程間共享。Java提供ThreadLocal類來(lái)支持線程局部變量轻局,是一種實(shí)現(xiàn)線程安全的方式洪鸭。

但是在管理環(huán)境下(如 web 服務(wù)器)使用線程局部變量的時(shí)候要特別小心样刷,在這種情況下,工作線程的生命周期比任何應(yīng)用變量的生命周期都要長(zhǎng)览爵。任何線程局部變量一旦在工作完成后沒有釋放置鼻,Java 應(yīng)用就存在內(nèi)存泄露的風(fēng)險(xiǎn)。

52.說(shuō)一下 synchronized 底層實(shí)現(xiàn)原理蜓竹?

synchronized可以保證方法或者代碼塊在運(yùn)行時(shí)箕母,同一時(shí)刻只有一個(gè)方法可以進(jìn)入到臨界區(qū),同時(shí)它還可以保證共享變量的內(nèi)存可見性俱济。

Java中每一個(gè)對(duì)象都可以作為鎖嘶是,這是synchronized實(shí)現(xiàn)同步的基礎(chǔ):

  • 普通同步方法,鎖是當(dāng)前實(shí)例對(duì)象

  • 靜態(tài)同步方法姨蝴,鎖是當(dāng)前類的class對(duì)象

  • 同步方法塊,鎖是括號(hào)里面的對(duì)象

53.synchronized 和 volatile 的區(qū)別是什么肺缕?

  • volatile本質(zhì)是在告訴jvm當(dāng)前變量在寄存器(工作內(nèi)存)中的值是不確定的左医,需要從主存中讀取同木;synchronized則是鎖定當(dāng)前變量浮梢,只有當(dāng)前線程可以訪問該變量,其他線程被阻塞住彤路。

  • volatile僅能使用在變量級(jí)別秕硝;synchronized則可以使用在變量、方法洲尊、和類級(jí)別的远豺。

  • volatile僅能實(shí)現(xiàn)變量的修改可見性,不能保證原子性坞嘀;而synchronized則可以保證變量的修改可見性和原子性躯护。

  • volatile不會(huì)造成線程的阻塞;synchronized可能會(huì)造成線程的阻塞丽涩。

  • volatile標(biāo)記的變量不會(huì)被編譯器優(yōu)化棺滞;synchronized標(biāo)記的變量可以被編譯器優(yōu)化。

54.synchronized 和 Lock 有什么區(qū)別矢渊?

  • 首先synchronized是java內(nèi)置關(guān)鍵字继准,在jvm層面,Lock是個(gè)java類矮男;

  • synchronized無(wú)法判斷是否獲取鎖的狀態(tài)移必,Lock可以判斷是否獲取到鎖;

  • synchronized會(huì)自動(dòng)釋放鎖(a 線程執(zhí)行完同步代碼會(huì)釋放鎖 毡鉴;b 線程執(zhí)行過(guò)程中發(fā)生異常會(huì)釋放鎖)避凝,Lock需在finally中手工釋放鎖(unlock()方法釋放鎖)舞萄,否則容易造成線程死鎖;

  • 用synchronized關(guān)鍵字的兩個(gè)線程1和線程2管削,如果當(dāng)前線程1獲得鎖倒脓,線程2線程等待。如果線程1阻塞含思,線程2則會(huì)一直等待下去崎弃,而Lock鎖就不一定會(huì)等待下去,如果嘗試獲取不到鎖含潘,線程可以不用一直等待就結(jié)束了饲做;

  • synchronized的鎖可重入、不可中斷遏弱、非公平盆均,而Lock鎖可重入、可判斷漱逸、可公平(兩者皆可)泪姨;

  • Lock鎖適合大量同步的代碼的同步問題,synchronized鎖適合代碼少量的同步問題饰抒。

55.synchronized 和 ReentrantLock 區(qū)別是什么肮砾?

synchronized是和if、else袋坑、for仗处、while一樣的關(guān)鍵字,ReentrantLock是類枣宫,這是二者的本質(zhì)區(qū)別婆誓。既然ReentrantLock是類,那么它就提供了比synchronized更多更靈活的特性也颤,可以被繼承旷档、可以有方法、可以有各種各樣的類變量歇拆,ReentrantLock比synchronized的擴(kuò)展性體現(xiàn)在幾點(diǎn)上:

  • ReentrantLock可以對(duì)獲取鎖的等待時(shí)間進(jìn)行設(shè)置鞋屈,這樣就避免了死鎖

  • ReentrantLock可以獲取各種鎖的信息

  • ReentrantLock可以靈活地實(shí)現(xiàn)多路通知

另外,二者的鎖機(jī)制其實(shí)也是不一樣的:ReentrantLock底層調(diào)用的是Unsafe的park方法加鎖故觅,synchronized操作的應(yīng)該是對(duì)象頭中mark word厂庇。

56.說(shuō)一下 atomic 的原理?

Atomic包中的類基本的特性就是在多線程環(huán)境下输吏,當(dāng)有多個(gè)線程同時(shí)對(duì)單個(gè)(包括基本類型及引用類型)變量進(jìn)行操作時(shí)权旷,具有排他性,即當(dāng)多個(gè)線程同時(shí)對(duì)該變量的值進(jìn)行更新時(shí),僅有一個(gè)線程能成功拄氯,而未成功的線程可以向自旋鎖一樣躲查,繼續(xù)嘗試,一直等到執(zhí)行成功译柏。

Atomic系列的類中的核心方法都會(huì)調(diào)用unsafe類中的幾個(gè)本地方法镣煮。我們需要先知道一個(gè)東西就是Unsafe類,全名為:sun.misc.Unsafe鄙麦,這個(gè)類包含了大量的對(duì)C代碼的操作典唇,包括很多直接內(nèi)存分配以及原子操作的調(diào)用,而它之所以標(biāo)記為非安全的胯府,是告訴你這個(gè)里面大量的方法調(diào)用都會(huì)存在安全隱患介衔,需要小心使用,否則會(huì)導(dǎo)致嚴(yán)重的后果骂因,例如在通過(guò)unsafe分配內(nèi)存的時(shí)候炎咖,如果自己指定某些區(qū)域可能會(huì)導(dǎo)致一些類似C++一樣的指針越界到其他進(jìn)程的問題。

文章轉(zhuǎn)載自:
經(jīng)典Java面試題的答案——多線程

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末寒波,一起剝皮案震驚了整個(gè)濱河市乘盼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌影所,老刑警劉巖蹦肴,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件僚碎,死亡現(xiàn)場(chǎng)離奇詭異猴娩,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)勺阐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門卷中,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人渊抽,你說(shuō)我怎么就攤上這事蟆豫。” “怎么了懒闷?”我有些...
    開封第一講書人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵十减,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我愤估,道長(zhǎng)帮辟,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任玩焰,我火速辦了婚禮由驹,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘昔园。我一直安慰自己蔓榄,他們只是感情好并炮,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著甥郑,像睡著了一般逃魄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上壹若,一...
    開封第一講書人閱讀 51,365評(píng)論 1 302
  • 那天嗅钻,我揣著相機(jī)與錄音,去河邊找鬼店展。 笑死养篓,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的赂蕴。 我是一名探鬼主播柳弄,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼概说!你這毒婦竟也來(lái)了碧注?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤糖赔,失蹤者是張志新(化名)和其女友劉穎萍丐,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體放典,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡逝变,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了奋构。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片壳影。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖弥臼,靈堂內(nèi)的尸體忽然破棺而出宴咧,到底是詐尸還是另有隱情,我是刑警寧澤径缅,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布掺栅,位于F島的核電站,受9級(jí)特大地震影響纳猪,放射性物質(zhì)發(fā)生泄漏氧卧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一兆旬、第九天 我趴在偏房一處隱蔽的房頂上張望假抄。 院中可真熱鬧,春花似錦、人聲如沸宿饱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)谬以。三九已至强饮,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間为黎,已是汗流浹背邮丰。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留铭乾,地道東北人剪廉。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像炕檩,于是被迫代替她去往敵國(guó)和親斗蒋。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容