一、Java 的 ConcurrentHashMap
在討論 computeIfAbsent 方法之前,我們需要先了解一下 Java 中的 ConcurrentHashMap。ConcurrentHashMap 是一個線程安全的哈希表,實現了 Map 介面。它被設計用來支持高並發,因為它可以在多個線程同時訪問一個或多個桶(buckets)而不會出現數據不一致的情況。
ConcurrentHashMap 的實現方式與 HashMap 不同。它將哈希表分為許多桶,並且每個桶都是一個單獨的鎖。當一個線程訪問哈希表的某個桶時,只有這個桶被鎖定,其他線程可以同時訪問其他桶。這使得 ConcurrentHashMap 可以支持高並發。
ConcurrentHashMap map = new ConcurrentHashMap();
二、computeIfAbsent 方法的定義和作用
1、什麼是 computeIfAbsent 方法
computeIfAbsent 方法是 ConcurrentHashMap 中的一個方法。它的作用是:如果指定的 key 在 map 中不存在,那麼就使用指定的函數計算它的值,並將 key-value 對添加到 map 中。如果指定的 key 已經存在於 map 中,則返回其對應的 value 值。
2、computeIfAbsent 方法的定義
computeIfAbsent 方法的定義如下:
default V computeIfAbsent(K key, Function mappingFunction)
其中,參數 key 表示要操作的 key,參數 mappingFunction 表示計算 key 對應的 value 的函數,它的類型為 Function。
3、computeIfAbsent 方法的作用
當調用 computeIfAbsent 方法時,ConcurrentHashMap 會檢查指定的 key 是否已經存在於哈希表中。如果 key 已經存在,則將與之關聯的 value 返回。如果 key 不存在,則傳遞給 computeIfAbsent 方法的 mappingFunction 函數將被調用。該函數將 key 作為參數,返回一個新的 value。新的 key-value 對將自動添加到 ConcurrentHashMap 中,並且 computeIfAbsent 會返回新的 value。
三、computeIfAbsent 方法的使用
下面我們來看一個 computeIfAbsent 方法的使用示例。代碼中使用了 ConcurrentHashMap,裡面存放了若干個 Fruit 對象,每個 Fruit 對象包含了水果的名稱和價格。
import java.util.concurrent.ConcurrentHashMap; class Fruit { private String name; private int price; public Fruit(String name, int price) { this.name = name; this.price = price; } public String getName() { return name; } public int getPrice() { return price; } } public class ConcurrentHashMapDemo { public static void main(String[] args) { ConcurrentHashMap map = new ConcurrentHashMap(); // 果盤裡沒有蘋果,就添加一個蘋果對象 Fruit apple = map.computeIfAbsent("apple", key -> new Fruit("apple", 2)); System.out.println(apple.getName() + ": " + apple.getPrice()); // 果盤裡已經有蘋果了,就不需要再新建一個蘋果對象了 Fruit anotherApple = map.computeIfAbsent("apple", key -> new Fruit("another apple", 3)); System.out.println(anotherApple.getName() + ": " + anotherApple.getPrice()); } }
運行上述代碼,輸出結果如下:
apple: 2 apple: 2
我們可以看到,第一次調用 computeIfAbsent 方法時,果盤裡沒有蘋果,因此新建了一個名為 “apple” 的蘋果對象,並將其添加到 map 中。第二次調用 computeIfAbsent 方法時,果盤裡已經有了一個名為 “apple” 的蘋果對象,因此第二個參數中的 lambda 表達式不會被執行,而是直接返回 map 中已有的蘋果對象。
四、computeIfAbsent 方法的優點
使用 computeIfAbsent 方法可以省略掉一些 if 判斷和 synchronized 同步,因為 computeIfAbsent 已經保證了線程安全。此外,在使用 computeIfAbsent 方法時,我們可以像示例代碼中一樣使用 lambda 表達式,使代碼更加簡潔易讀。
五、小結
在 Java 中,ConcurrentHashMap 是一個支持高並發的線程安全 Map。它提供了許多常用的方法,其中包括 computeIfAbsent 方法。使用 computeIfAbsent 方法可以有效地處理多線程並發的問題,同時也能使代碼更加簡潔易讀。在實際開發中,我們應該充分發揮 ConcurrentHashMap 的優勢,使用 computeIfAbsent 方法來實現線程安全的數據處理。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/238152.html