Java面試之多執行緒&併發篇(3)

码路编程發表於2024-11-14

前言

本來想著給自己放鬆一下,刷刷部落格,突然被幾道面試題難倒!SynchronizedMap和ConcurrentHashMap有什麼區別?什麼是執行緒安全?Thread類中的yield方法有什麼作用?Java執行緒池中submit() 和 execute()方法有什麼區別?似乎有點模糊了,那就大概看一下面試題吧。好記性不如爛鍵盤

*** 12萬字的java面試題整理 ***
*** java核心面試知識整理 ***

SynchronizedMap和ConcurrentHashMap有什麼區別?

SynchronizedMap()和Hashtable一樣,實現上在呼叫map所有方法時,都對整個map進行同步。所以,只要有一個執行緒訪問map,其他執行緒就無法進入map。
而ConcurrentHashMap的實現卻更加精細,它對map中的所有桶加了鎖。而如果一個執行緒在訪問ConcurrentHashMap某個桶時,其他執行緒,仍然可以對map執行某些操作。

所以,ConcurrentHashMap在效能以及安全性方面,明顯比Collections.synchronizedMap()更加有優勢。同時,同步操作精確控制到桶,這樣,即使在遍歷map時,如果其他執行緒試圖對map進行資料修改,也不會丟擲ConcurrentModificationException。

什麼是執行緒安全

執行緒安全就是說多執行緒訪問同一段程式碼,不會產生不確定的結果。
又是一個理論的問題,各式各樣的答案有很多,我給出一個個人認為解釋地最好的:
如果你的程式碼在多執行緒下執行和在單執行緒下執行永遠都能獲得一樣的結果,那麼你的程式碼就是執行緒安全的。這個問題有值得一提的地方,就是執行緒安全也是有幾個級別的:

  1. 不可變
    像String、Integer、Long這些,都是final型別的類,任何一個執行緒都改變不了它們的值,要改變除非新建立一個,因此這些不可變物件不需要任何同步手段就可以直接在多執行緒環境下使用
  2. 絕對執行緒安全
    不管執行時環境如何,呼叫者都不需要額外的同步措施。要做到這一點通常需要付出許多額外的代價,Java中標註自己是執行緒安全的類,實際上絕大多數都不是執行緒安全的,不過絕對執行緒安全的類,Java中也有,比方說CopyOnWriteArrayList、CopyOnWriteArraySet
  3. 相對執行緒安全
    相對執行緒安全也就是我們通常意義上所說的執行緒安全,像Vector這種,add、remove方法都是原子操作,不會被打斷,但也僅限於此,如果有個執行緒在遍歷某個Vector、有個執行緒同時在add這個Vector,99%的情況下都會出現ConcurrentModificationException,也就是fail-fast機制。
  4. 執行緒非安全這個就沒什麼好說的了,ArrayList、LinkedList、HashMap等都是執行緒非安全的類

Thread類中的yield方法有什麼作用?

Yield方法可以暫停當前正在執行的執行緒物件,讓其它有相同優先順序的執行緒執行。它是一個靜態方法而且只保證當前執行緒放棄CPU佔用而不能保證使其它執行緒一定能佔用CPU,執行yield()的執行緒有可能在進入到暫停狀態後馬上又被執行。

Java執行緒池中submit() 和 execute()方法有什麼區別?

兩個方法都可以向執行緒池提交任務,execute()方法的返回型別是void,它定義在Executor介面中,而submit()方法可以返回持有計算結果的Future物件,它定義在ExecutorService介面中,它擴充套件了Executor介面,其它執行緒池類像ThreadPoolExecutor和ScheduledThreadPoolExecutor都有這些方法。

相關文章