天天看點

day 23-24 面試題:synchronized和volatile的差別;final,finally,finalize差別

面試題:

1. synchronized和volatile的差別
2. final,finally,finalize差別
           

1. synchronized和volatile的差別

1.1 JVM記憶體模型

JVM将記憶體組織分為主記憶體和工作記憶體兩部分。

  1. 主記憶體

    主記憶體包括方法區和堆。所有變量都存在主記憶體中,對于所有線程都是共享的。

  2. 工作記憶體

    每一個線程有一個工作記憶體,它包含兩部分,該線程的私有棧和對主存部分變量拷貝的寄存器(包括程式計數器PC和CPU工作的高速緩存區)。

多線程模型下,每個工作線程不能通路另一個工作線程中的變量,線程間變量傳遞是通過主線程來完成的。是以可能存在這種情況,線程1對變量a進行指派了,還沒來得及寫入記憶體中,線程2不知道線程1已修改變量a的值,繼續使用a原來的值,這樣就會出現問題。

1.2 volatile

volatile是java的關鍵字,使用volatile修飾的變量會強制将修改的值立即寫入主存,主存中的值更新會使工作線程中的副本值失效。

  • 保證記憶體可見性:某個線程修改了volatitle修飾的變量值,其他線程能夠及時知道。
  • 禁止指令重排序:當程式執行到volatitle修飾的變量的讀寫操作時,可以保證之前的語句已執行完,也能确定後面的邏輯還未執行
  • 不保證原子性:volatitle不保證變量的任何操作都是原子性的,比如i++

1.3 synchronized

synchronized依賴于JVM,保證了同一時刻隻能有一個線程在作用對象的作用範圍内進行操作。

  • 記憶體可見性:線程在加鎖時,先清空工作記憶體->在主存中拷貝最新變量副本到工作線程->執行完代碼->将更改後的共享變量刷到主存中->釋放互斥鎖
  • 操作的原子性:因為synchronized保證了同一時間隻有一個線程對代碼塊進行操作,是以操作是原子性的。
  • 有序性:第一條的特性決定,在多線程環境中,代碼執行是有序的。

1.4 volatile和synchronized的差別

  1. volatile不會加鎖,比synchronized更輕量級,不會阻塞線程
  2. volatile标記的變量不會被編譯器優化而synchronized可以(比如編譯器重排優化)
  3. volatile是變量修飾符,而synchronized可以修改方法、變量、代碼塊、
  4. volatile不保證原子性,synchronized可以保證原子性
  5. 他們都能保證記憶體可見性

2. final,finally,finalize差別

2.1 final

final是個修飾詞,可以修飾類,方法和屬性

  1. 修飾類

    final修飾的類不能被繼承。

  2. 修飾方法

    主要由兩個原因

    • 防止被繼承,修改
    • 早期java版本中性能優化
  3. 修飾屬性

    使用final修飾的屬性,一旦初始化後就不能修改 ,可以了解該屬性隻能讀不能改。

2.2 finally

finally做為異常處理的一部分,隻能用在try/catch語句中,如果try語句被執行那麼finally語句也肯定被執行(除非把程序殺掉了等異常情況)。

2.3 finalize

finalize()方法是在Object裡定義的,在對象被回收時調用。一般情況下不需要手動去實作該方法。

如果非要調用,得調用其super方法。

2.4 final,finally,finalize差別

其實他們沒有半毛錢關系,隻是長得像

繼續閱讀