public class redislock
/***/
public redislock( string lockkey, int timeoutmsecs)
/***
*/public redislock( string lockkey, int timeoutmsecs, int expiremsecs)
/***/
public string getlockkey()
private string get(final string key) catch (exception e) ", key);
}finally
}return res;
}/**
* 嘗試獲取鎖
* @return 是否獲取成功
*/public boolean trygetlock()
} catch (exception e) ", lockkey);
}finally
}return false;
}/**
*/public synchronized void unlock()
jedis.del(lockkey);
date keydate=new date(long.parselong(res.split("_")[0]));
jedis.hdel("lock_"+dateformatutil.format(keydate, "yyyy-mm-dd_hh_mm"),lockkey);
}locked = false;
} catch (exception e) ", lockkey);
}finally }}
}/**
* 獲得 lock.
* 實現思路: 主要是使用了redis 的setnx命令,快取了鎖.
* reids快取的key是鎖的key,所有的共享, value是鎖過期時間+執行緒id+執行緒hashcode+鎖物件hashcode
* 執行過程:
* 1.通過setnx嘗試設定某個key的值,成功(當前沒有這個鎖)則返回,成功獲得鎖
* 2.鎖已經存在則獲取鎖的到期時間,和當前時間比較,超時的話,則設定新的值
* 3.鎖的內容 新增 執行緒id 以及 執行緒hashcode ,用於處理 同一執行緒下,多層子邏輯需要對同乙個資料重複加鎖異常的問題 對比判斷如果是同一執行緒的子操作,則預設已經鎖定,無需鎖等待以及重複鎖
* 4.鎖的內容 新增 加鎖物件本身hashcode ,為了解鎖的時候對比判斷是不是 加鎖的那個物件執行的解鎖操作, 避免多層業務 重複鎖, 子操作 解鎖導致,鎖被非正常解鎖**/
public synchronized boolean lock() throws interruptedexception
string currentvaluestr = this.get(lockkey); //redis裡的時間
long cachetime=long.parselong(currentvaluestr.split("_")[0]);
long threadid=long.parselong(currentvaluestr.split("_")[1]);
int threadhashcode=integer.parseint(currentvaluestr.split("_")[2]);
thread thread=thread.currentthread();
if(threadhashcode==thread.hashcode()&&threadid==thread.getid())
if (currentvaluestr != null &&cachetime+expiremsecs + 1 < system.currenttimemillis())
timeout -= default_acquiry_resolution_millis;
/*延遲100 毫秒, 這裡使用隨機時間可能會好一點,可以防止飢餓程序的出現,即,當同時到達多個程序,
只會有乙個程序獲得鎖,其他的都用同樣的頻率進行嘗試,後面有來了一些進行,也以同樣的頻率申請鎖,這將可能導致前面來的鎖得不到滿足.
使用隨機的等待時間可以一定程度上保證公平性
*/thread.sleep(default_acquiry_resolution_millis);
}return false;
}}
Redis SETNX 命令實現分布式鎖
setnx命令簡介 命令格式 setnx key value將 key 的值設為 value,當且僅當 key 不存在。若給定的 key 已經存在,則 setnx 不做任何動作。setnx 是set if not exists的簡寫。返回值返回整數,具體為 1,當 key 的值被設定 0,當 key...
Redis SETNX命令實現分布式鎖
命令格式 setnx key value 將 key 的值設為 value,當且僅當 key 不存在。若給定的 key 已經存在,則 setnx 不做任何動作。setnx 是set if not exists的簡寫。返回值 設定成功,返回 1 設定失敗,返回 0 使用redis實現分布式全域性鎖 演...
使用Redis SETNX 命令實現分布式鎖
使用redis的 setnx 命令可以實現分布式鎖,下文介紹其實現方法。setnx key value 將 key 的值設為 value,當且僅當 key 不存在。若給定的 key 已經存在,則 setnx 不做任何動作。setnx 是set if not exists的簡寫。返回整數,具體為 1,...