強烈推薦乙個大神的人工智慧的教程:
四、zookeeper實現分布式鎖
五、資料庫實現
多工環境
任務都需要對同一共享資源進行寫操作
對資源的訪問是互斥的
**塊加synchronized鎖或者reentrantlock鎖
if(setnx(key,1) == 1) finally
}
存在的問題:命令不是原子操作,可能出現還沒有設定超時時間,服務宕機,導致鎖永遠存在
優化使用命令:
set(key,1,30,nx)
存在的問題:可能導致誤刪除,兩個執行緒都來拿鎖,a執行緒先獲得鎖之後,設定超時時間30s,在30s後執行緒還沒執行到del命令列,這時鎖就自己刪掉了,這時候b執行緒就可以拿到鎖,因此當a執行del的時候刪掉的就是b的鎖
優化:值為執行緒id,刪除時判斷是否是自己的key
加鎖:
string threadid = thread.currentthread().getid()
set(key,threadid ,30,nx)
解鎖:if(threadid .equals(redisclient.get(key)))
解決誤刪除問題:獲得鎖的執行緒開啟乙個守護執行緒,為這個鎖續時,每20s執行一次,給key延時20s
是乙個分布式協調服務
每乙個節點都是乙個znode
znode儲存的資料資訊。
acl:
記錄znode的訪問許可權,即哪些人或哪些ip可以訪問本節點。
stat:
包含znode的各種元資料,比如事務id、版本號、時間戳、大小等等。
child:
當前節點的子節點引用,類似於二叉樹的左孩子右孩子。
通過zab協議保證,採用二階段提交保證
* zk實現分布式鎖
*/@service
public class zookeeperimprovelock implements lock
}@override
//非阻塞時加鎖
public boolean trylock()
//獲取所有臨時節點並排序,臨時節點名稱為自增長的字串,如:00000000400
listchildren = this.client.getchildren(lock_path);
collections.sort(children);
system.out.println(children.tostring());
system.out.println(thread.currentthread().getname()+ "get0--->"+ children.get(0));
system.out.println(thread.currentthread().getname()+"currentpath"+ currentpath);
string realpath = lock_path+'/'+children.get(0);
system.out.println(thread.currentthread().getname()+ "real---"+ realpath);
if(currentpath.equals(realpath))else
int wz = collections.binarysearch(children,currentpath.substring(6));
beforepath = lock_path + '/' + children.get(wz-1);
system.out.println(thread.currentthread().getname()+"beforepath"+ beforepath);
}} catch (runtimeexception e)
return false;
}@override
public void lock() else
}private void waitforlock()
@override
public void handledatadeleted(string s) throws exception }};
//給排在前面的節點增加資料刪除的watcher
this.client.subscribedatachanges(beforepath,listener);
if(this.client.exists(beforepath)) catch (interruptedexception e)
}this.client.unsubscribedatachanges(beforepath,listener);
}@override
public void lockinterruptibly() throws interruptedexception
@override
public boolean trylock(long time, timeunit unit) throws interruptedexception
@override
public void unlock()
@override
public condition newcondition()
}唯一索引
行級鎖
/**
* mysql實現分布式鎖
*///@service
public class mysqllock implements lock catch (interruptedexception e)
lock();}}
// 非阻塞式的實現
public boolean trylock() catch (exception e)
return true;
}// 解鎖
public void unlock()
public condition newcondition()
public void lockinterruptibly() throws interruptedexception
public boolean trylock(long time, timeunit unit) throws interruptedexception
}
Redis分布式鎖原理及實現
ps 該篇博文目錄為 redis分布式鎖使用 中的 有瑕疵,為避免錯誤使用,請移步 感興趣的也可以看看到底瑕疵在哪 解決問題 多個程序多台機器,對乙個資料進行的操作的互斥。比如,下訂單和扣庫存的操作,這兩個操作必須連貫,乙個執行緒執行完這兩個操作後,下面乙個執行緒才可以介入執行,如果同時併發執行,極...
分布式鎖實現原理
拜託,面試請不要再問我redis分布式鎖的實現原理!石杉的架構筆記 可重入鎖 為什麼不建議使用redis分布鎖 主從切換可能丟失鎖資訊 考慮一下這樣的場景 在分布式環境中,很多併發需要鎖來同步,當使用redis分布式鎖,通用的做法是使用redis的setnx key value px 這樣的命令,設...
分布式鎖 哨兵模式 分布式鎖實現原理
背景 記錄對分布式鎖的相關理解,不斷提公升自己 可重入鎖 為什麼不建議使用redis分布鎖 主從切換可能丟失鎖資訊 考慮一下這樣的場景 在分布式環境中,很多併發需要鎖來同步,當使用redis分布式鎖,通用的做法是使用redis的setnx key value px 這樣的命令,設定乙個字段,當設定成...