Zookeeper:实现节点Barriers(即限定操作)

1.声明

当前内容主要用于本人学习和复习之用,当前内容主要为使用Zookeeper实现壁垒的方式控制当前线程什么时候停止什么时候继续

当前内容来源:Barriers伪代码流程

2.查看分析流程

  1. 客户端调用当前的exists方法,并设置watch为true的方式,设置path为壁垒barrier节点
  2. 如果当前的exists方法返回的是false,那么这个壁垒消失,客户端继续前进
  3. 如果当前的exists方法返回的是true,那么当前的客户端等待从barrier获取监控事件,获取壁垒barrier节点
  4. 当监控事件触发的时候,该客户端重新发出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.通过为当前壁垒不停的添加监控的事件方式(节点删除)来唤醒当前线程的执行

以上纯属个人见解,如有问题请联本人!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章