zookeeper分佈式鎖

 

zookeeper有java兩種客戶端  zookeeper和CuratorFramework

 

一:線程不安全時候的代碼,生成訂單號爲例子

final static CuratorFramework client = CuratorFrameworkFactory.builder()
			.connectString("120.77.156.44:2181")
			.retryPolicy(new ExponentialBackoffRetry(100,1))
			.build();
	static int num =1;
	public static void main(String[] args) throws InterruptedException {
		ExecutorService executorService = Executors.newCachedThreadPool();
		final CountDownLatch countDownLatch = new CountDownLatch(1);
		for(int i=0;i<10;i++) {
			executorService.submit(new Runnable() {
				@Override
				public void run() {
					try {
						countDownLatch.await();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					System.out.println(Thread.currentThread().getName()+"---->"+getOrder());
				}
			});
		} 
		countDownLatch.countDown();
		executorService.shutdown();
	}
	
	//生成訂單號的鎖
	public static String getOrder() {
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		int k = num++;
		return "testOrder"+k;
	}

運行結果爲:

 

 

二:用CuratorFramework 來實現zook鎖

pom:

 

<dependency>
			<groupId>org.apache.curator</groupId>
			<artifactId>curator-framework</artifactId>
			<version>2.9.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.curator</groupId>
			<artifactId>curator-recipes</artifactId>
			<version>2.9.0</version>
		</dependency>

 

 

 

 

java:

final static CuratorFramework client = CuratorFrameworkFactory.builder()
			.connectString("120.77.156.44:2181")
			.retryPolicy(new ExponentialBackoffRetry(100,1))
			.build();
	static int num =1;
	public static void main(String[] args) throws InterruptedException {
		client.start();
		ExecutorService executorService = Executors.newCachedThreadPool();
		final CountDownLatch countDownLatch = new CountDownLatch(1);
		final InterProcessMutex lock = new InterProcessMutex(client, "/test11");
		for(int i=0;i<10;i++) {
			executorService.submit(new Runnable() {
				@Override
				public void run() {
					try {
						countDownLatch.await();
						try {
							lock.acquire();
						} catch (Exception e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					System.out.println(Thread.currentThread().getName()+"---->"+getOrder());
					try {
						lock.release();
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			});
		} 
		countDownLatch.countDown();
		executorService.shutdown();
	}
	
	//生成訂單號的鎖
	public static String getOrder() {
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		int k = num++;
		return "testOrder"+k;
	}

運行結果:

 

 

 

 

三:zookeeper客戶端鎖(簡單粗暴版)

pom:

                <dependency>
			<groupId>org.apache.zookeeper</groupId>
			<artifactId>zookeeper</artifactId>
			<version>3.4.12</version>
		</dependency>

java:

static ZooKeeper zk = null;
	static{
		try {
			zk=new ZooKeeper("120.77.156.44:2181", 3000, new Watcher() {
				public void process(WatchedEvent event) {
			        System.out.println(event);
			    }
			});
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static void main(String[] args) throws InterruptedException, KeeperException {
		ExecutorService executorService = Executors.newCachedThreadPool();
		final CountDownLatch countDownLatch = new CountDownLatch(1);
		for(int i=0;i<10;i++) {
			executorService.submit(new Runnable() {
				@Override
				public void run() {
					try {
						countDownLatch.await();
						lock();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					System.out.println(Thread.currentThread().getName()+"---->"+getOrder());
					unlock();
				}
			});
		} 
		countDownLatch.countDown();
		executorService.shutdown(); 
	}
	static int num =1;
	public static String getOrder() {
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		int k = num++;
		return "testOrder"+k;
	}
	public static void lock() {
		try {
			zk.create("/test/lock", "test".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
		} catch (Exception e) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e1) {
			}
			lock();
		}
	}
	public static void  unlock() {
		try {
			zk.delete("/test/lock", -1);
		} catch (Exception e) {
			System.out.println("delete no");
		}
//		System.out.println("delete success");
	}

運行結果:

 

 

 

 

4:zookeeper鎖

public class MyLock implements Watcher{
	static String root = "/test/lock";
	ZooKeeper zKeeper;
	String path;
	private String currentNode;
	private String waitNode;
	CountDownLatch latch;
	public MyLock(String path,String host) {
		try {
			zKeeper = new ZooKeeper(host, 1000, this);
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		this.path = path;
		try {
			Stat node = zKeeper.exists(root, false);
			if(node==null) {
				zKeeper.create(root, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
			}
		} catch (KeeperException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	public void lock(){
		try {
			currentNode = zKeeper.create(root+"/"+path, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
		} catch (KeeperException | InterruptedException e) {
			e.printStackTrace();
		}
		try {
			List<String> lockObjectNode = zKeeper.getChildren(root, false);
			Collections.sort(lockObjectNode);
			if(currentNode.equals(root+"/"+lockObjectNode.get(0))) {
				return;
			}else {
				//截取  /test/lock/lock00001 中的lock00001
				String key = currentNode.substring(currentNode.lastIndexOf("/")+1);
				//找到鎖的位置
				int index = Collections.binarySearch(lockObjectNode, key);
				waitNode = lockObjectNode.get(index-1); //獲取等待節點
				Stat stat = zKeeper.exists(root+"/"+waitNode, true);
				if(null!=stat) {
					latch = new CountDownLatch(1);
					this.latch.await(5000,TimeUnit.MILLISECONDS);
				}
			}
		} catch (KeeperException | InterruptedException e) {
			e.printStackTrace();
		}
	}
	public void unLock() {
		try {
			//刪除當前的節點
			zKeeper.delete(currentNode, -1);
			currentNode=null;
			zKeeper.close();
		} catch (InterruptedException | KeeperException e) {
			e.printStackTrace();
		}
	}
	@Override
	public void process(WatchedEvent arg0) {
		if(null!=latch) {
			latch.countDown();
		}
	}
}

 

 

 

 

 

 

 

 

 

 

 

 

 

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