Java 面試專題 - 多線程&并發(fā)編程

1缺狠、說說進(jìn)程问慎、線程、協(xié)程之間的區(qū)別

簡而言之挤茄,進(jìn)程是程序運行和資源分配的基本單位如叼,一個程序至少有一個進(jìn)程,一個進(jìn)程至少有一個線程。進(jìn)程在執(zhí)行過程中擁有獨立的內(nèi)存單元穷劈,而多個線程共享內(nèi)存資源笼恰,減少切換次數(shù),從而效率更高歇终。

線程是進(jìn)程的一個實體社证,是cpu調(diào)度和分派的基本單位,是比程序更小的能獨立運行的基本單位。同一進(jìn)程中的多個線程之間可以并發(fā)執(zhí)行评凝。

2追葡、什么是守護線程?它和非守護線程有什么區(qū)別

程序運行完畢,JVM會等待非守護線程完成后關(guān)閉,但是jvm不會等待守護線程宜肉。守護線程最典型的例子就是GC線程疾渣。

3、線程的狀態(tài)有哪些

請參考我的另外一篇文章:Java 線程的狀態(tài)及切換

4崖飘、創(chuàng)建兩種線程的方式?他們有什么區(qū)別?

  • 通過實現(xiàn)java.lang.Runnable

  • 通過擴展java.lang.Thread類.
    相比擴展Thread,實現(xiàn)Runnable接口可能更優(yōu).原因有二:

  • Java不支持多繼承榴捡,因此擴展Thread類就代表這個子類不能擴展其他類.而實現(xiàn)Runnable接口的類還可能擴展另一個類。

  • 類可能只要求可執(zhí)行即可朱浴,因此集成整個Thread類的開銷過大吊圾。

5、Runnable和Callable的區(qū)別

Runnable接口中的run()方法的返回值是void翰蠢,它做的事情只是純粹地去執(zhí)行run()方法中的代碼而已项乒; Callable接口中的call()方法是有返回值的,是一個泛型梁沧,和Future檀何、FutureTask配合可以用來獲取異步執(zhí)行的結(jié)果。

這其實是很有用的一個特性廷支,因為多線程相比單線程更難频鉴、更復(fù)雜的一個重要原因就是因為多線程充滿著未知性, 某條線程是否執(zhí)行了恋拍?某條線程執(zhí)行了多久垛孔?某條線程執(zhí)行的時候我們期望的數(shù)據(jù)是否已經(jīng)賦值完畢?無法得知施敢,我們能做的只是等待這條多線程的任務(wù)執(zhí)行完畢而已周荐。 而Callable+Future/FutureTask卻可以獲取多線程運行的結(jié)果,可以在等待時間太長沒獲取到需要的數(shù)據(jù)的情況下取消該線程的任務(wù)僵娃,真的是非常有用概作。

6、Thread yield和join 區(qū)別

Thread.yield() 使得線程放棄當(dāng)前分得的 CPU 時間默怨,但是不使線程阻塞讯榕,即線程仍處于可執(zhí)行狀態(tài),隨時可能再次分得 CPU 時間先壕。調(diào)用 yield() 的效果等價于調(diào)度程序認(rèn)為該線程已執(zhí)行了足夠的時間從而轉(zhuǎn)到另一個線程瘩扼。

Thread.join 把指定的線程加入到當(dāng)前線程,可以將兩個交替執(zhí)行的線程合并為順序執(zhí)行的線程垃僚。比如在線程B中調(diào)用了線程A的join()方法集绰,那么直到線程A執(zhí)行完畢后,才會繼續(xù)執(zhí)行線程B谆棺。

7栽燕、synchronized和ReentrantLock的區(qū)別

synchronized是和if罕袋、else、for碍岔、while一樣的關(guān)鍵字浴讯,ReentrantLock是類,這是二者的本質(zhì)區(qū)別蔼啦。 既然ReentrantLock是類榆纽,那么它就提供了比synchronized更多更靈活的特性,可以被繼承捏肢、可以有方法奈籽、可以有各種各樣的類變量,ReentrantLock比synchronized的擴展性體現(xiàn)在幾點上:

  • ReentrantLock可以對獲取鎖的等待時間進(jìn)行設(shè)置鸵赫,這樣就避免了死鎖
  • ReentrantLock可以獲取各種鎖的信息
  • ReentrantLock可以靈活地實現(xiàn)多路通知
    另外衣屏,二者的鎖機制其實也是不一樣的:ReentrantLock底層調(diào)用的是Unsafe的park方法加鎖,synchronized操作的應(yīng)該是對象頭中mark word辩棒。

8狼忱、AtomicInteger 內(nèi)部實現(xiàn)

其實就是 CAS + volatile,參考:Java AtomicInteger原理分析

9一睁、如何在兩個線程間共享數(shù)據(jù)

通過在線程之間共享對象就可以了钻弄,然后通過wait/notify/notifyAll、await/signal/signalAll進(jìn)行喚起和等待卖局,比方說阻塞隊列BlockingQueue就是為線程之間共享數(shù)據(jù)而設(shè)計的斧蜕。

10、ThreadLoal 實現(xiàn)原理

簡單說ThreadLocal就是一種以空間換時間的做法在每個Thread里面維護了一個ThreadLocal砚偶。ThreadLocalMap把數(shù)據(jù)進(jìn)行隔離,數(shù)據(jù)不共享洒闸,自然就沒有線程安全方面的問題了染坯。

詳細(xì)參考:ThreadLocal源碼深入分析

11、ThreadPoolExecutor 構(gòu)造參數(shù)有哪些丘逸?各代表什么意義单鹿?

ThreadPoolExecutor pool = new ThreadPoolExecutor(10, 20, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(20), new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                return null;
            }
        });

默認(rèn)rejectHandler是 AbortPolicy,其它還有:DiscardPolicy深纲,DiscardOldestPolicy仲锄, CallerRunsPolicy。

12湃鹊、ConcurrentHashMap 實現(xiàn)原理

ConcurrentHashMap是由Segment數(shù)組結(jié)構(gòu)和HashEntry數(shù)組結(jié)構(gòu)組成儒喊。Segment是一種可重入鎖ReentrantLock,在ConcurrentHashMap里扮演鎖的角色币呵,HashEntry則用于存儲鍵值對數(shù)據(jù)怀愧。一個ConcurrentHashMap里包含一個Segment數(shù)組,Segment的結(jié)構(gòu)和HashMap類似,是一種數(shù)組和鏈表結(jié)構(gòu)芯义, 一個Segment里包含一個HashEntry數(shù)組哈垢,每個HashEntry是一個鏈表結(jié)構(gòu)的元素, 每個Segment守護者一個HashEntry數(shù)組里的元素,當(dāng)對HashEntry數(shù)組的數(shù)據(jù)進(jìn)行修改時扛拨,必須首先獲得它對應(yīng)的Segment鎖耘分。

詳細(xì)參考:聊聊并發(fā)(四)——深入分析ConcurrentHashMap

13、volatile關(guān)鍵字的作用

簡單的說绑警,就是當(dāng)你寫一個 volatile 變量之前陶贼,Java 內(nèi)存模型會插入一個寫屏障(write barrier),讀一個 volatile 變量之前待秃,會插入一個讀屏障(read barrier)拜秧。 意思就是說,在你寫一個 volatile 域時章郁,能保證任何線程都能看到你寫的值枉氮,同時,在寫之前暖庄,也能保證任何數(shù)值的更新對所有線程是可見的聊替,因為內(nèi)存屏障會將其他所有寫的值更新到緩存。
volatile關(guān)鍵字可以保證 可見性和 禁止指令重排序培廓。

在Java虛擬機規(guī)范中試圖定義一種Java內(nèi)存模型(Java Memory Model惹悄,JMM)來屏蔽各個硬件平臺和操作系統(tǒng)的內(nèi)存訪問差異,以實現(xiàn)讓Java程序在各種平臺下都能達(dá)到一致的內(nèi)存訪問效果肩钠。Java語言 本身對 原子性泣港、可見性以及有序性。

1价匠、原子性

在Java中当纱,對基本數(shù)據(jù)類型的變量的讀取和賦值操作是原子性操作,即這些操作是不可被中斷的踩窖,要么執(zhí)行坡氯,要么不執(zhí)行。

2洋腮、可見性

對于可見性箫柳,Java提供了volatile關(guān)鍵字來保證可見性。
  當(dāng)一個共享變量被volatile修飾時啥供,它會保證修改的值會立即被更新到主存悯恍,當(dāng)有其他線程需要讀取時,它會去內(nèi)存中讀取新值滤灯。
  而普通的共享變量不能保證可見性坪稽,因為普通共享變量被修改之后曼玩,什么時候被寫入主存是不確定的,當(dāng)其他線程去讀取時窒百,此時內(nèi)存中可能還是原來的舊值黍判,因此無法保證可見性。
  另外篙梢,通過synchronized和Lock也能夠保證可見性顷帖,synchronized和Lock能保證同一時刻只有一個線程獲取鎖然后執(zhí)行同步代碼,并且在釋放鎖之前會將對變量的修改刷新到主存當(dāng)中渤滞。因此可以保證可見性贬墩。

3、有序性

在Java內(nèi)存模型中妄呕,允許編譯器和處理器對指令進(jìn)行重排序陶舞,但是重排序過程不會影響到單線程程序的執(zhí)行,卻會影響到多線程并發(fā)執(zhí)行的正確性绪励。

在Java里面肿孵,可以通過volatile關(guān)鍵字來保證一定的“有序性”(具體原理在下一節(jié)講述)。另外可以通過synchronized和Lock來保證有序性疏魏,
很顯然停做,synchronized和Lock保證每個時刻是有一個線程執(zhí)行同步代碼,相當(dāng)于是讓線程順序執(zhí)行同步代碼大莫,自然就保證了有序性蛉腌。

14、CyclicBarrier和CountDownLatch區(qū)別

這兩個類非常類似只厘,都在java.util.concurrent下烙丛,都可以用來表示代碼運行到某個點上,二者的區(qū)別在于:

  • CyclicBarrier的某個線程運行到某個點上之后懈凹,該線程即停止運行蜀变,直到所有的線程都到達(dá)了這個點,所有線程才重新運行介评;CountDownLatch則不是,某線程運行到某個點上之后爬舰,只是給某個數(shù)值-1而已们陆,該線程繼續(xù)運行
  • CyclicBarrier只能喚起一個任務(wù),CountDownLatch可以喚起多個任務(wù)
  • CyclicBarrier可重用情屹,CountDownLatch不可重用坪仇,計數(shù)值為0該CountDownLatch就不可再用了

15、有哪些多線程開發(fā)良好的實踐?

  • 給線程命名垃你;
  • 最小化同步范圍椅文;
  • 優(yōu)先使用volatile喂很;
  • 盡可能使用更高層次的并發(fā)工具而非wait和notify()來實現(xiàn)線程通信,如BlockingQueue,Semeaphore皆刺;
  • 優(yōu)先使用并發(fā)容器而非同步容器少辣;
  • 考慮使用線程池

本文將會不定期更新,歡迎大家持續(xù)關(guān)注羡蛾!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末漓帅,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子痴怨,更是在濱河造成了極大的恐慌忙干,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浪藻,死亡現(xiàn)場離奇詭異捐迫,居然都是意外死亡,警方通過查閱死者的電腦和手機爱葵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進(jìn)店門施戴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人钧惧,你說我怎么就攤上這事暇韧。” “怎么了浓瞪?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵懈玻,是天一觀的道長。 經(jīng)常有香客問我乾颁,道長涂乌,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任英岭,我火速辦了婚禮湾盒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘诅妹。我一直安慰自己罚勾,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布吭狡。 她就那樣靜靜地躺著尖殃,像睡著了一般。 火紅的嫁衣襯著肌膚如雪划煮。 梳的紋絲不亂的頭發(fā)上送丰,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天,我揣著相機與錄音弛秋,去河邊找鬼器躏。 笑死俐载,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的登失。 我是一名探鬼主播遏佣,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼壁畸!你這毒婦竟也來了贼急?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤捏萍,失蹤者是張志新(化名)和其女友劉穎太抓,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體令杈,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡走敌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了逗噩。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片掉丽。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖异雁,靈堂內(nèi)的尸體忽然破棺而出捶障,到底是詐尸還是另有隱情,我是刑警寧澤纲刀,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布项炼,位于F島的核電站,受9級特大地震影響示绊,放射性物質(zhì)發(fā)生泄漏锭部。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一面褐、第九天 我趴在偏房一處隱蔽的房頂上張望拌禾。 院中可真熱鬧,春花似錦展哭、人聲如沸湃窍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽坝咐。三九已至,卻和暖如春析恢,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背秧饮。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工映挂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留泽篮,地道東北人。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓柑船,卻偏偏與公主長得像帽撑,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子鞍时,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,601評論 2 353

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