java synchronized 保護執行緒安全

r涤生發表於2024-06-21

前言

工作中自己實現了一個MySessionContext類,在實現addSession方法的時候,考慮到會有執行緒不安全問題,這裡需要使用synchronized關鍵字來保護執行緒安全。


理解 synchronized 關鍵字需要了解多執行緒和執行緒安全的基本概念。在多執行緒環境中,多個執行緒可以同時訪問共享資源(例如記憶體中的變數或物件)。如果這些訪問沒有正確同步,就可能導致資料不一致和其他問題。

多執行緒與執行緒安全

多執行緒:在一個程式中同時執行多個執行緒,每個執行緒執行不同的任務。
執行緒安全:指多個執行緒訪問共享資源時,保證資源的完整性和一致性。

執行緒不安全問題

假設有一個共享資源 sessionMap(一個 Map<String, HttpSession> 物件),多個執行緒同時向這個 Map 新增會話物件。如果沒有同步機制,可能會出現以下問題:

  1. 資料不一致:多個執行緒同時寫入 sessionMap,可能導致某些寫操作丟失或覆蓋其他寫操作。
  2. 競爭條件:多個執行緒競爭訪問同一個資源,導致程式行為不可預測。
  3. 空指標異常:如果一個執行緒在另一個執行緒完成寫入之前讀取資料,可能會得到不完整或錯誤的資料。

synchronized 關鍵字

Synchronized 關鍵字提供了一種機制,確保在同一時刻只有一個執行緒可以執行同步程式碼塊,從而避免上述問題。

例子:執行緒不安全的程式碼

public void addSession(HttpSession session) {
    if (session != null) {
        sessionMap.put(session.getId(), session);
    }
}

在這個例子中,如果多個執行緒同時呼叫 addSession 方法,可能會同時執行 sessionMap.put() 操作,導致資料不一致。

例子:使用 synchronized 關鍵字確保執行緒安全

public synchronized void addSession(HttpSession session) {
    if (session != null) {
        sessionMap.put(session.getId(), session);
    }
}

使用 synchronized 關鍵字可以確保同一時間只有一個執行緒可以執行 addSession 方法,避免競爭條件和資料不一致的問題。

詳細解釋 synchronized 的作用

同步方法:在方法定義上使用 synchronized 關鍵字,如 public synchronized void addSession(HttpSession session),確保同一時間只有一個執行緒可以執行這個方法。

同步塊:你也可以使用同步塊來保護共享資源。

public void addSession(HttpSession session) {
    if (session != null) {
        synchronized(this) {
            sessionMap.put(session.getId(), session);
        }
    }
}

synchronized 的執行機制

當一個執行緒進入 synchronized 方法或同步塊時,它會獲得該方法或塊對應物件的鎖(monitor)。
其他執行緒必須等待,直到當前執行緒釋放鎖之後,才能進入該同步方法或同步塊。
這樣可以確保同一時間只有一個執行緒訪問被保護的程式碼塊,從而保證執行緒安全。

小結

使用 synchronized 關鍵字,可以確保同一時刻只有一個執行緒執行特定的方法或程式碼塊。這種機制透過鎖(monitor)來實現,防止多個執行緒同時訪問共享資源,從而避免資料不一致和其他執行緒安全問題。

相關文章