1.聲明
當前內容主要用於本人學習和複習之用,當前內容主要爲使用Zookeeper實現壁壘的方式控制當前線程什麼時候停止什麼時候繼續
當前內容來源:Barriers僞代碼流程
2.查看分析流程
- 客戶端調用當前的exists方法,並設置watch爲true的方式,設置path爲壁壘barrier節點
- 如果當前的exists方法返回的是false,那麼這個壁壘消失,客戶端繼續前進
- 如果當前的exists方法返回的是true,那麼當前的客戶端等待從barrier獲取監控事件,獲取壁壘barrier節點
- 當監控事件觸發的時候,該客戶端重新發出exists調用,再次等待直到移除壁壘節點
下面使用java代碼方式實現該壁壘的操作
1.首先開啓zookeeper,地址爲:192.168.1.105:2181
/**
* @description 當前內容用於實現當前Zookeeper上面的Barriers僞代碼
* @author hy
* @date 2020-06-07
*/
public class BarriersTest {
static ZooKeeper zk;
static {
try {
zk=new ZooKeeper("192.168.1.105", 10000, null);
} catch (IOException e) {
System.out.println("初始化失敗。。。。");
}
}
//static Watcher watch = ;
static Object mointer =new Object();
public static void main(String[] args) throws KeeperException, InterruptedException {
/*
* 1. Client calls the ZooKeeper API's exists() function on the barrier node,with watch set to true.
* 2. If exists() returns false, the barrier is gone and the client proceeds
* 3. Else, if exists() returns true, the clients wait for a watch event from ZooKeeper for the barrier node.
* 4. When the watch event is triggered, the client reissues the exists( ) call, again waiting until the barrier node is removed.
*/
// 上面是僞代碼
// 1. 客戶端調用當前的exists方法並設置watch爲true的方式,在當前的壁壘barrier節點
// 2. 如果當前的exists方法返回的是false,那麼這個壁壘消失,客戶端繼續前進
// 3.如果當前的exists方法返回的是true,那麼當前的客戶端等待從barrier獲取監控事件,獲取壁壘barrier節點
// 4.當監控事件觸發的時候,該客戶端重新發出exists調用,再次等待直到移除壁壘節點
String barrierNode = "/barrier";
while(true){
synchronized (mointer) {
// 1. 客戶端調用當前的exists方法並設置watch爲true的方式,在當前的壁壘barrier節點
boolean exists = exists(barrierNode);
if (exists) {
// 3.如果當前的exists方法返回的是true,那麼當前的客戶端等待從barrier獲取監控事件,獲取壁壘barrier節點
System.out.println("等待監控事件的觸發。。。。");
// 等待獲取監控事件
mointer.wait();
} else {
// 2. 如果當前的exists方法返回的是false,那麼這個壁壘消失,客戶端繼續前進
System.out.println("客戶端繼續前進。。。。");
Thread.sleep(2000L);
}
}
}
}
public static boolean exists(String barrierNode) throws KeeperException, InterruptedException {
Stat stat = zk.exists(barrierNode, new DefaultWatcher(barrierNode));
return stat != null;
}
static class DefaultWatcher implements Watcher {
private String barrierNode;
public DefaultWatcher(String barrierNode) {
this.barrierNode = barrierNode;
}
@Override
public void process(WatchedEvent event) {
try {
synchronized (mointer) {
System.out.println("觸發監控事件。。。。。。。。。。");
// 4.當監控事件觸發的時候,該客戶端重新發出exists調用,再次等待直到移除壁壘節點
if(EventType.NodeDeleted == event.getType()) {
// 壁壘節點被移除的事件
System.out.println("觸發節點刪除事件。。。。。。。。。。");
mointer.notify();
}
exists(barrierNode);
}
} catch (KeeperException | InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
3.開始測試
1.啓動當前的zookeeper
2.啓動當前的java客戶端
3.爲當前的zookeeper創建壁壘節點
create /barrier ""
4.查看當前的控制檯
此時發現線程已近停止,並沒有持續輸出:客戶端前進。。。
5.刪除壁壘節點
delete /barrier
測試成功
4.總結
1.當前的壁壘實現主要是通過一個標記觸發的,這個標記就是壁壘節點是否存在
2.通過爲當前壁壘不停的添加監控的事件方式(節點刪除)來喚醒當前線程的執行
以上純屬個人見解,如有問題請聯本人!