120道Java面試題以及答案

2020-08-14 23:07:50

多執行緒、併發及執行緒的基礎問題
1)Java 中能建立 volatile 陣列嗎?
能,Java 中可以建立 volatile 型別陣列,不過只是一個指向陣列的參照,而不是整個陣列。我的意思是,如果改變參照指向的陣列,將會受到 volatile 的保護,但是如果多個執行緒同時改變陣列的元素,volatile 標示符就不能起到之前的保護作用了。
2)volatile 能使得一個非原子操作變成原子操作嗎?
一個典型的例子是在類中有一個 long 型別的成員變數。如果你知道該成員變數會被多個執行緒存取,如計數器、價格等,你最好是將其設定爲 volatile。爲什麼?因爲 Java 中讀取 long 型別變數不是原子的,需要分成兩步,如果一個執行緒正在修改該 long 變數的值,另一個執行緒可能只能看到該值的一半(前 32 位)。但是對一個 volatile 型的 long 或 double 變數的讀寫是原子。
3)volatile 修飾符的有過什麼實踐?
一種實踐是用 volatile 修飾 long 和 double 變數,使其能按原子型別來讀寫。double 和 long 都是64位元寬,因此對這兩種型別的讀是分爲兩部分的,第一次讀取第一個 32 位,然後再讀剩下的 32 位,這個過程不是原子的,但 Java 中 volatile 型的 long 或 double 變數的讀寫是原子的。volatile 修復符的另一個作用是提供記憶體屏障(memory barrier),例如在分佈式框架中的應用。簡單的說,就是當你寫一個 volatile 變數之前,Java 記憶體模型會插入一個寫屏障(write barrier),讀一個 volatile 變數之前,會插入一個讀屏障(read barrier)。意思就是說,在你寫一個 volatile 域時,能保證任何執行緒都能看到你寫的值,同時,在寫之前,也能保證任何數值的更新對所有執行緒是可見的,因爲記憶體屏障會將其他所有寫的值更新到快取。
4)volatile 型別變數提供什麼保證?
volatile 變數提供順序和可見性保證,例如,JVM 或者 JIT爲了獲得更好的效能會對語句重排序,但是 volatile 型別變數即使在沒有同步塊的情況下賦值也不會與其他語句重排序。 volat