引言
Java中的Map類是一種常用的數據結構,常用的實現類包括HashMap、ConcurrentHashMap、LinkedHashMap等。在Map中,putIfAbsent函數是一個比較常用的方法,但是它的作用可能不太清晰。本文將通過多個方面來詳細闡釋Java中putIfAbsent函數的使用方法。
正文
一、putIfAbsent函數的定義
/** * 如果給定的鍵尚未與某個值相關聯(或映射到null),則將其與給定的值相關聯並返回null,否則返回當前值。 * * @param key 鍵 * @param value 值 * @return 與key關聯的舊值,如果沒有則返回null。 */ public V putIfAbsent(K key, V value);
上述代碼摘自Java8的HashMap類,putIfAbsent函數具有一個很明確的作用:如果給定的鍵還沒有值,那麼將此鍵值對插入到Map中,並返回null,如果給定的鍵已經有值,則返回當前存儲的值,不進行插入。
二、putIfAbsent的使用示例
Map map = new HashMap();
Object oldVal = map.putIfAbsent("key", "value");
System.out.println(oldVal); // null
Object newVal = map.putIfAbsent("key", "value2");
System.out.println(newVal); // value
從上述代碼可以看出,首先向Map中插入鍵為「key」,值為「value」的鍵值對,由於之前Map中沒有此鍵,所以putIfAbsent方法返回null。接着又嘗試插入鍵為「key」,值為「value2」的鍵值對,由於Map中已有此鍵,所以putIfAbsent方法返回當前存儲的值「value」。
三、putIfAbsent方法的線程安全性
雖然putIfAbsent方法線程安全,在多線程環境下運行也不會產生死鎖等問題,但是仍有一些需要注意的地方。
首先需要說明的是,putIfAbsent方法的線程安全性是針對單個鍵值對而言的。也就是說,不同的線程可以同時操作不同的鍵值對,但是如果操作的是同一個鍵值對,那麼就要考慮線程安全問題了。
Map map = new ConcurrentHashMap();
ExecutorService service = Executors.newFixedThreadPool(3);
service.submit(() -> map.putIfAbsent("key", 1));
service.submit(() -> map.putIfAbsent("key", 2));
service.submit(() -> map.putIfAbsent("key", 3));
從上述代碼可以看出,在創建ConcurrentHashMap實例並提交三個線程執行putIfAbsent方法操作同一個鍵值對時,線程間可能產生競爭,會出現多個線程操作同一個鍵值對的情況。在這種情況下,我們需要通過加鎖或使用ConcurrentHashMap等線程安全的Map實現來解決。
四、putIfAbsent方法在代碼中的實際應用場景
實際應用場景中,putIfAbsent方法也有很多場景。
1. 緩存數據
private Map cache = new ConcurrentHashMap();
public Object getData(String key) {
// 先從緩存中獲取數據
Object data = cache.get(key);
if (data == null) {
// 如果緩存中沒有數據,則從數據庫中讀取,並添加到緩存
data = fetchDataFromDB(key); // 假設這個方法從數據庫中獲取數據
cache.putIfAbsent(key, data);
}
return data;
}
緩存數據是putIfAbsent方法常用的場景之一,上述代碼邏輯是先從緩存中獲取數據,如果緩存中沒有數據則從數據庫中獲取,然後將獲取到的數據添加到緩存中
2. 分佈式鎖
public boolean acquireLock(String lockKey, String owner) {
// 其他線程已經獲取到鎖
if (cache.containsKey(lockKey)) {
return false;
} else {
// 嘗試獲取分佈式鎖
if (cache.putIfAbsent(lockKey, owner) == null) {
return true;
} else {
return false;
}
}
}
public void releaseLock(String lockKey, String owner) {
// 釋放分佈式鎖
cache.remove(lockKey, owner);
}
分佈式鎖也是putIfAbsent方法的一個常見應用場景。上述代碼通過向緩存添加鍵值對形式的鎖實現分佈式鎖,如果lockKey已經存在,則說明其他線程已經獲得了鎖,無法獲取,否則可以獲得鎖。
總結
本文詳細闡述了Java中putIfAbsent方法的定義、使用示例、線程安全性、實際應用場景等方面。putIfAbsent方法是Map類的重要方法之一,在實際編程過程中如果掌握了這個方法的使用方法,可以讓代碼更加簡潔、高效。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/230544.html
微信掃一掃
支付寶掃一掃