Java試題筆試題目答案

來源:才華庫 2.84W

1)Java 中能建立 Volatile 陣列嗎?

Java試題筆試題目答案

能,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 型別變數即使在沒有同步塊的情況下賦值也不會與其他語句重排序。 volatile 提供 happens—before 的保證,確保一個執行緒的修改能對其他執行緒是可見的。某些情況下,volatile 還能提供原子性,如讀 64 位資料型別,像 long 和 double 都不是原子的,但 volatile 型別的 double 和 long 就是原子的。

5) 10 個執行緒和 2 個執行緒的同步程式碼,哪個更容易寫?

從寫程式碼的角度來說,兩者的複雜度是相同的,因為同步程式碼與執行緒數量是相互獨立的。但是同步策略的選擇依賴於執行緒的數量,因為越多的執行緒意味著更大的競爭,所以你需要利用同步技術,如鎖分離,這要求更復雜的程式碼和專業知識

6)你是如何呼叫 wait()方法的?使用 if 塊還是迴圈?為什麼?(答案)

wait() 方法應該在迴圈呼叫,因為當執行緒獲取到 CPU 開始執行的時候,其他條件可能還沒有滿足,所以在處理前,迴圈檢測條件是否滿足會更好。下面是一段標準的使用 wait 和 notify 方法的程式碼:

// The standard idiom for using the wait method

參見 Effective Java 第 69 條,獲取更多關於為什麼應該在迴圈中來呼叫 wait 方法的內容。

熱門標籤