在Java中,鎖是用于控制訪問共享資源的機制。當多個線程試圖訪問同一資源時,我們需要確保在一個時間點只能有一個線程訪問該資源。
對于線程的訪問,Java中有兩種基本的鎖機制:樂觀鎖和悲觀鎖。
樂觀鎖
樂觀鎖機制假設在大多數情況下,沖突不會發生,因此不需要加鎖來保護共享資源。例如,在使用Java ConcurrentHashMap時,它將使用樂觀鎖機制來實現線程安全。
ConcurrentHashMap<K, V> map = new ConcurrentHashMap<>(); map.put(key, value); // 通過CAS(Compare And Swap)進行更新操作 map.computeIfPresent(key, (k, v) -> updateFunction(v));
在此示例中,computeIfPresent方法使用CAS操作更新值而不是加鎖。
悲觀鎖
悲觀鎖機制假設沖突經常發生,因此需要加鎖來保護共享資源。例如,在Java中使用synchronized和ReentrantLock都可以實現悲觀鎖。
public class Counter { private int count = 0; private final Object lock = new Object(); public void increment() { synchronized (lock) { count++; } } public int getCount() { synchronized (lock) { return count; } } }
在此示例中,使用synchronized關鍵字對increment()和getCount()方法進行加鎖,以使它們在同一時間只能被一個線程訪問。
結論
使用樂觀鎖和悲觀鎖都可以保證線程安全,但取決于鎖的使用場合和具體實現。在多線程環境下,使用適當的鎖機制能夠避免競爭條件和死鎖等問題的發生。