在Java多線程開發中,鎖(Lock)是一種用于控制多個線程訪問共享資源的機制。Java中提供了兩種鎖機制:synchronized和Lock。其中,synchronized是基于Java語言的內置鎖機制,Lock是Java5及以后版本提供的一個可重入、有條件的鎖機制。
相對于synchronized,Lock更加靈活,可控性更高,可以通過tryLock、lockInterruptibly等方法滿足不同的業務需求。但未加鎖的代碼仍舊會被其他線程執行,所以在使用Lock時要注意仔細處理加鎖、解鎖的邏輯,否則會出現資源競爭、死鎖等問題。
而Redis作為一種高性能的開源key-value內存數據庫,也提供了一種分布式鎖機制,即Redis分布式鎖。該機制基于Redis的setnx和expire命令實現,具有以下特點:
/** * 分布式鎖實現 * @param key 鎖名 * @param value 請求ID * @param expireTime 過期時間(單位:秒) * @return 是否成功獲取鎖 */ public boolean tryLock(String key, String value, int expireTime){ String msg = jedis.set(key, value, "NX", "EX", expireTime); return msg != null && msg.equalsIgnoreCase("OK"); } /** * 釋放鎖 * @param key 鎖名 * @param value 請求ID * @return 是否成功釋放鎖 */ public boolean releaseLock(String key, String value){ String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"; Object result = jedis.eval(script, Collections.singletonList(key), Collections.singletonList(value)); return result != null && Long.parseLong(result.toString()) == 1L; }
以上是Redis分布式鎖的示例代碼。其中,tryLock方法嘗試獲取一把鎖,如果成功則返回true,否則返回false;releaseLock方法釋放一把鎖,確保該鎖屬于當前請求ID,如果釋放成功則返回true,否則返回false。使用時,可以結合Redis的watch命令實現串行化執行,保證多個線程同時只有一個線程獲取到鎖。
上一篇java的難點和重點