java大公司后端多线程面试题最强分享
點擊上方“好好學java”,選擇“置頂公眾號”
優秀學習資源、干貨第一時間送達!
?精彩內容?
java實戰練習項目教程
2018微服務資源springboot、springcloud、docker、dubbo實戰等傾心分享
2018年java架構師全套學習教程
最新大數據培訓完整視頻教程
2018年java最新全套培訓學習教程
29、java中用到的線程調度算法是什么
搶占式。一個線程用完CPU之后,操作系統會根據線程優先級、線程饑餓情況等數據算出一個總的優先級并分配下一個時間片給某個線程執行。
30、Thread.sleep(0)的作用是什么
由于Java采用搶占式的線程調度算法,因此可能會出現某條線程常常獲取到CPU控制權的情況,為了讓某些優先級比較低的線程也能獲取到CPU控制權,可以使用Thread.sleep(0)手動觸發一次操作系統分配時間片的操作,這也是平衡CPU控制權的一種操作。
31、什么是CAS
CAS,全稱為Compare and Swap,即比較-替換。假設有三個操作數:內存值V、舊的預期值A、要修改的值B,當且僅當預期值A和內存值V相同時,才會將內存值修改為B并返回true,否則什么都不做并返回false。當然CAS一定要volatile變量配合,這樣才能保證每次拿到的變量是主內存中最新的那個值,否則舊的預期值A對某條線程來說,永遠是一個不會變的值A,只要某次CAS操作失敗,永遠都不可能成功
32、什么是樂觀鎖和悲觀鎖
樂觀鎖:樂觀鎖認為競爭不總是會發生,因此它不需要持有鎖,將比較-替換這兩個動作作為一個原子操作嘗試去修改內存中的變量,如果失敗則表示發生沖突,那么就應該有相應的重試邏輯。
悲觀鎖:悲觀鎖認為競爭總是會發生,因此每次對某資源進行操作時,都會持有一個獨占的鎖,就像synchronized,不管三七二十一,直接上了鎖就操作資源了。
33、ConcurrentHashMap的并發度是什么?
ConcurrentHashMap的并發度就是segment的大小,默認為16,這意味著最多同時可以有16條線程操作ConcurrentHashMap,這也是ConcurrentHashMap對Hashtable的最大優勢,任何情況下,Hashtable能同時有兩條線程獲取Hashtable中的數據嗎?
34、ConcurrentHashMap的工作原理
ConcurrentHashMap在jdk 1.6和jdk 1.8實現原理是不同的.
jdk 1.6:
ConcurrentHashMap是線程安全的,但是與Hashtablea相比,實現線程安全的方式不同。Hashtable是通過對hash表結構進行鎖定,是阻塞式的,當一個線程占有這個鎖時,其他線程必須阻塞等待其釋放鎖。ConcurrentHashMap是采用分離鎖的方式,它并沒有對整個hash表進行鎖定,而是局部鎖定,也就是說當一個線程占有這個局部鎖時,不影響其他線程對hash表其他地方的訪問。
具體實現:ConcurrentHashMap內部有一個Segment
jdk 1.8
在jdk 8中,ConcurrentHashMap不再使用Segment分離鎖,而是采用一種樂觀鎖CAS算法來實現同步問題,但其底層還是“數組+鏈表->紅黑樹”的實現。
37、CyclicBarrier和CountDownLatch區別
這兩個類非常類似,都在java.util.concurrent下,都可以用來表示代碼運行到某個點上,二者的區別在于:
CyclicBarrier的某個線程運行到某個點上之后,該線程即停止運行,直到所有的線程都到達了這個點,所有線程才重新運行;CountDownLatch則不是,某線程運行到某個點上之后,只是給某個數值-1而已,該線程繼續運行
CyclicBarrier只能喚起一個任務,CountDownLatch可以喚起多個任務
CyclicBarrier可重用,CountDownLatch不可重用,計數值為0該CountDownLatch就不可再用了
39、java中的++操作符線程安全么?
不是線程安全的操作。它涉及到多個指令,如讀取變量值,增加,然后存儲回內存,這個過程可能會出現多個線程交差
40、你有哪些多線程開發良好的實踐?
給線程命名
最小化同步范圍
優先使用volatile
盡可能使用更高層次的并發工具而非wait和notify()來實現線程通信,如BlockingQueue,Semeaphore
優先使用并發容器而非同步容器.
考慮使用線程池
關于volatile關鍵字
1、可以創建Volatile數組嗎?
Java 中可以創建 volatile類型數組,不過只是一個指向數組的引用,而不是整個數組。如果改變引用指向的數組,將會受到volatile 的保護,但是如果多個線程同時改變數組的元素,volatile標示符就不能起到之前的保護作用了
2、volatile能使得一個非原子操作變成原子操作嗎?
一個典型的例子是在類中有一個 long 類型的成員變量。如果你知道該成員變量會被多個線程訪問,如計數器、價格等,你最好是將其設置為 volatile。為什么?因為 Java 中讀取 long 類型變量不是原子的,需要分成兩步,如果一個線程正在修改該 long 變量的值,另一個線程可能只能看到該值的一半(前 32 位)。但是對一個 volatile 型的 long 或 double 變量的讀寫是原子。
一種實踐是用 volatile 修飾 long 和 double 變量,使其能按原子類型來讀寫。double 和 long 都是64位寬,因此對這兩種類型的讀是分為兩部分的,第一次讀取第一個 32 位,然后再讀剩下的 32 位,這個過程不是原子的,但 Java 中 volatile 型的 long 或 double 變量的讀寫是原子的。volatile 修復符的另一個作用是提供內存屏障(memory barrier),例如在分布式框架中的應用。簡單的說,就是當你寫一個 volatile 變量之前,Java 內存模型會插入一個寫屏障(write barrier),讀一個 volatile 變量之前,會插入一個讀屏障(read barrier)。意思就是說,在你寫一個 volatile 域時,能保證任何線程都能看到你寫的值,同時,在寫之前,也能保證任何數值的更新對所有線程是可見的,因為內存屏障會將其他所有寫的值更新到緩存。
3、volatile類型變量提供什么保證?
volatile 主要有兩方面的作用:1.避免指令重排2.可見性保證.例如,JVM 或者 JIT為了獲得更好的性能會對語句重排序,但是 volatile 類型變量即使在沒有同步塊的情況下賦值也不會與其他語句重排序。 volatile 提供 happens-before 的保證,確保一個線程的修改能對其他線程是可見的。某些情況下,volatile 還能提供原子性,如讀 64 位數據類型,像 long 和 double 都不是原子的(低32位和高32位),但 volatile 類型的 double 和 long 就是原子的.
推薦閱讀
1.?每日都見到的springboot日志
2.?springmvc入門
3.?servlet就是這么簡單
4.?重溫javaweb過濾器filter
附上熱門QQ群,存放資源和歷史資料,2000容量(低門檻付費群),長按二維碼入群
總結
以上是生活随笔為你收集整理的java大公司后端多线程面试题最强分享的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 近两年火热的微服务springboot不
- 下一篇: Java多线程面试准备:聊聊Execut