public interface lock {

    void getLock();

    void unLock();
}
public abstract class ZkAbstractLock implements lock{
//zk连接地址
private static final String CONNECTSTRING = "127.0.0.1:2181";
//创建zk连接
protected ZkClient zkClient = new ZkClient(CONNECTSTRING);
//PATH
protected static final String PATH = "/lock";
public abstract boolean tryLock();
public abstract void waitLock();
public void getLock() {
if (tryLock()) {
System.out.println("###成功获取锁###");
} else {
waitLock();
getLock();
}
} public void unLock() {
if(zkClient!=null){
zkClient.close();
System.out.println("###释放所资源###");
}
}
}

**
* @Auther:
* @Date: 星期一:2019/4/29 15
* @Description: zk基于异常的阻塞式锁
*/
public class ZKExceptionLock extends ZkAbstractLock {
private String lockPath;
private CountDownLatch countDownLatch = new CountDownLatch(1); public ZKExceptionLock(String lockPath) {
this.lockPath = PATH + "/" + lockPath;
}
public boolean tryLock() {
try {
zkClient.createEphemeral(lockPath);
return true;
}catch (Exception e){
return false;
}
} public void waitLock() {
zkClient.subscribeDataChanges(lockPath, new IZkDataListener() {
public void handleDataChange(String s, Object o) throws Exception {
System.out.println("---handleDataChange---");
} public void handleDataDeleted(String s) throws Exception {
countDownLatch.countDown();
}
}); try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void unLock(){
zkClient.delete(lockPath);
}
}
/**
* @Auther:
* @Date: 星期一:2019/4/29 12
* @Description: zk基于监听的阻塞式锁
*/
public class ZkListenerLock extends ZkAbstractLock {
private static final CountDownLatch LATCH = new CountDownLatch(1);
private String lockPath;
private String currentPath;
private String beforePath; public ZkListenerLock(String lockPath) {
if (!zkClient.exists(PATH)) {
zkClient.createPersistent(PATH);
}
this.lockPath = PATH+"/"+lockPath;
if (!zkClient.exists(this.lockPath)) {
System.out.println("-----------");
zkClient.createPersistent(this.lockPath);
}
} public boolean tryLock() {
if (null == currentPath || currentPath.length()<=0 ) {
currentPath = zkClient.createEphemeralSequential(lockPath + "/", "lock");
}
List<String> children = zkClient.getChildren(lockPath);//0000000007
Collections.sort(children);
System.out.println(children);
if (currentPath.equals(lockPath + "/"+children.get(0))) {
return true;
}
String key = currentPath.substring(lockPath.length() + 1);
int location = Collections.binarySearch(children, key);
this.beforePath = lockPath + "/" + children.get(location - 1);
return false;
} public void waitLock() {
IZkDataListener listener = new IZkDataListener() {
public void handleDataChange(String s, Object o) throws Exception {
System.out.println("--handleDataChange--");
}
public void handleDataDeleted(String s) throws Exception {
LATCH.countDown();
}
};
zkClient.subscribeDataChanges(this.beforePath,listener);
if (!zkClient.exists(this.beforePath)) {
return;
}
try {
LATCH.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
zkClient.unsubscribeDataChanges(this.beforePath,listener);
} @Override
public void unLock() {
zkClient.delete(currentPath);
}
}
public class TestLock {
public static void main(String[] args) { int i = 0;
while (i < 10) {
People people = new People();
people.start();
i++;
}
System.out.println(People.totalMoney);
}
static class People extends Thread{
private ZkListenerLock lock = new ZkListenerLock("order");
private ZKExceptionLock lock2 = new ZKExceptionLock("order2");
public static int totalMoney = 50;
public void run(){
try {
//获取锁资源
lock2.getLock();
totalMoney--;
} catch (Exception e) {
e.printStackTrace();
} finally {
//释放锁资源
lock2.unLock();
}
}
}
}
 

基于监听的zk锁:L值就是建立有序节点后返回的序列号

基于异常的zk锁:

pom.xml:

<dependencies>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.3.2</version>
</dependency>
</dependencies>

最新文章

  1. C# oracle odp.net 32位/64位版本的问题
  2. 关于全排列 next_permutation() 函数的用法
  3. nyoj366_D的小L_字典序_全排列
  4. git branch用法总结
  5. 分布式并行数据库将在OLTP 领域促进去“Oracle”
  6. 怎样查出SQLServer的性能瓶颈
  7. Spring Web Flow使用
  8. 69道java Spring面试题和答案
  9. HIVE Transform using 用法
  10. 手工配置tomcat 解决一闪而过~
  11. 我也谈“the difference between Factory, Service, and Provider in Angular”
  12. MJRefresh 使用注意点
  13. sqlserver 收缩数据库/文件
  14. leetcode — add-binary
  15. sum-root-to-leaf-numbers (前序遍历)
  16. materializecss的水波纹效果
  17. [UE4]在蓝图中设置图片
  18. SonarQube与Eclipse配合
  19. Jmeter 中对响应报文处理后断言用到BeanShell Assertion
  20. 【微信小程序】处理时间格式,时间戳转化展示时间格式问题,调用外部js的默认方法function的问题

热门文章

  1. 第二章&#160;向量(d2)有序向量:二分查找
  2. WebSphere Application Server中manageprofiles的使用
  3. APIcloud制作APP 微信支付与支付宝支付
  4. jQuery Grid高级指南
  5. Angular之输入输出属性
  6. Properties 使用
  7. linux命令学习之:curl
  8. Bootstrap(9) 巨幕页头缩略图和警告框组件
  9. Object转为Bigdecimal
  10. 关于thymeleaf的if多条件判断