面試還為多線程發愁?馬士兵出版《多線程高併發》帶你吊打面試官

併發編程相比 Java 中其他知識點學習起來門檻相對較高,學習起來比較費勁,從而導致很多人望而卻步;而無論是職場面試和高併發高流量的系統的實現卻都還離不開併發編程,從而導致能夠真正掌握併發編程的人才成為市場比較迫切需求的。

因此,大家不難發現 Java 併發問題一直是各個大廠面試的重點之一。我在平時的面試中,也發現很多候選人對一些基本的併發概念表示沒聽過,或原理不理解,可能知道一些卻又講不清楚,最終導致面試失敗。本文會結合實際中接觸到的一些面試題,重點來聊一聊 Java 併發中的相關知識點。

面試還為多線程發愁?馬士兵出版《多線程高併發》帶你吊打面試官

併發編程高級面試專題

Synchronized相關面試題集

問題一: Synchronized用過嗎,其原理是什麼?

問題二:你剛才提到獲取對象的鎖,這個“鎖"到底是什麼?如何確定對象的鎖?

問題三:什麼是可重入性,為什麼說Synchronized是可重入鎖?

問題四:JVM對Java的原生鎖做了哪些優化?

問題五:為什麼說Synchronized是非公平鎖?

問題六:什麼是鎖消除和鎖粗化?.

問題七:為什麼說Synchronized是一個 悲觀鎖?樂觀鎖的實現原理又是什麼?什麼是

問題八:樂觀鎖定就是好的嗎 ?

可重入鎖 ReentrantLock 及其他顯式鎖相關面試題集

問題一- : 跟Synchronized相比,可重入鎖ReentrantLock其實現原理有什麼不同?

問題二:那麼請談談AQS框架是怎麼回事兒?

問題三:請儘可能詳盡地對此下Synchronized和ReentrantLock的異同。

問題四: ReentrantLock是如何實現可重入性的?

問題五:除了ReetrantLock,你還接觸過JUC中的哪些併發工具?

問題六:請談談ReadWriteLock和StampedLock.

問題七:如何讓Java的線程彼此同步?你瞭解過哪些同步器?請分別介紹下。

Java 線程池相關問題

問題一: Java中的線程池是如何實現的?

問題二:創建線程池的幾個核心構造參數?

問題三:線程池中的線程是怎麼創建的?是一開始就隨著線程池的啟動創建好的嗎 ?

問題四:既然提到可以通過配置不同參數創建出不同的線程池,那麼Java中默認實現好的線程池又有哪些呢?請比較它們的異同。

問題五:如何在Java線程池中提交線程?

Java 內存模型相關問題

問題一:什麼是Java的內存模型,Java中各個線程是怎麼彼此看到對方的變量的?

問題二:請談談volatile有什麼特點,為什麼它能保證變量對所有線程的可見性?

問題三:既然volatile能夠保證線程間的變量可見性,是不是就意味著基於volatile 變量的運算就是併發安全的?

問題四:請對比下volatile對比Synchronized的異同。

問題五:請談談ThreadLocal是怎麼解決併發安全的?

問題六:很多人都說要慎用ThreadLocal,談談你的理解,使用ThreadLocal需要注意些什麼

面試題答案

1.Synchronized 用過嗎, 其原理是什麼?

這是一道 Java 面試中幾乎百分百會問到的問題, 因為沒有任何寫過併發程序的開發者會沒聽說或者沒接觸過 Synchronized。 Synchronized 是由 JVM 實現的一種實現互斥同步的一種方式, 如果你查看被Synchronized 修飾過的程序塊編譯後的字節碼, 會發現, 被 Synchronized 修飾過 的程序塊, 在編譯前後被編譯器生成了monitorenter 和 monitorexit 兩個字節碼指 令。這兩個指令是什麼意思呢? 在虛擬機執行到 monitorenter 指令時, 首先要嘗試獲取對象的鎖: 如果這個對象沒 有鎖定, 或者當前線程已經擁有了這個對象的鎖, 把鎖 的 計 數 器 +1; 當 執 行 monitorexit 指令時將鎖計 數 器 -1; 當計數器為0時 , 鎖就被 釋放了 。 如果獲取對象失敗了, 那當前線程就要阻塞等待, 直到對象鎖被另外一個線程釋放為 止。Java中Synchronize 通過在對象頭設置標記 , 達到了獲取鎖和釋放鎖的目的 。

2.跟Synchronized相比, 可重入鎖Reentrant Lock其實現原理有什麼不同?

其實, 鎖的實現原理基本是為了達到一個目的: 讓所有的線程都能看到某種標記。 Synchronized 通過在對象頭中設置標記實現了這一目的 , 是一種JVM原 生的鎖實現方式, 而 Reentrant Lock 以及所有的基於 Lock 接口的實現類, 都是通過用一個 volitile修飾的int型變量,並保證每個線程都能擁有對該int的可見性和原子修改, 其本質是基於所謂的 AQS 框架。

3. Java 中的線程池是如何實現的?

1.在 Java 中 , 所謂的線程池中的 “ 線 程 ” ,其 實 是 被 抽 象 為了一個靜態內部類 Worker, 它 基 於 AQS 實 現 , 存 放 在 線 程 池 的 Hash Set< Worker> workers 成 員 變 量 中 ; 2.而需要執行的任務則存放在成員變量 work Queue ( Blocking Queue< Runnable> work Queue) 中。 這樣 , 整個線程池實現的基本思想就是:從 work Queue中不斷取出需 要 執 行 的 任 務 , 放在Workers中進行處理 。

4.什麼是 Java 的內存模型, Java 中各個線程是怎麼彼此看到對方的變量的?

Java 的內存模型定義了程序中各個變量的訪問規則, 即在虛擬機中將變量存儲到內 存和從內存中取出這樣的底層細節。 此處的變量包括實例字段、 靜態字段和構成數組對象的元素, 但是不包括局部變量和 方法參數, 因為這些是線程私有的, 不會被共享, 所以不存在競爭問題。 Java 中各個線程是怎麼彼此看到對方的變量的呢?

Java中定義了主內存與工作內存 的概念: 所有的變量都存儲在主內存, 每條線程還有自己的工作內存, 保存了被該線程使用到 的變量的主內存副本拷貝。 線程對變量的所有操作( 讀取、 賦值) 都必須在工作內存中進行, 不能直接讀寫主 內存的變量。 不同的線程之間也無法直接訪問對方工作內存的變量, 線程間變量值的 傳遞需要通過主內存。

由於篇幅限制,太長看下去會很乏味,也會影響閱讀體驗,上面是每個題集的一題答案,下面展現將以圖片形式展示。獲取原文件以及更多資源請關注轉發分享後,後臺私信回覆【併發】獲取資料免費領取方式!

面試還為多線程發愁?馬士兵出版《多線程高併發》帶你吊打面試官

面試還為多線程發愁?馬士兵出版《多線程高併發》帶你吊打面試官

面試還為多線程發愁?馬士兵出版《多線程高併發》帶你吊打面試官


分享到:


相關文章: