引言
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-hant/n/230544.html