1、添加zookeeper依赖
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.13</version>
</dependency>
2、代码部分:
package com.imooc.lock;
import org.apache.zookeeper.*;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
/**
* @Author: dahai.li
* @Description: 基于zk实现分布式锁
* @Date: Create in 16:51 2019/8/27
*/
public class ZkLock {
private ZooKeeper zooKeeper;
private static CountDownLatch countDownLatch = new CountDownLatch(1);
private ZkLock() {
try {
zooKeeper = new ZooKeeper("192.1.1.101:2181,192.1.1.102:2181,192.1.1.103:2181",5000,new ZkWatcher(){});
System.out.println(zooKeeper.getState());
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static ZkLock getInstance(){
return Singleton.getInstance();
}
private class ZkWatcher implements Watcher {
@Override
public void process(WatchedEvent event) {
System.out.println("接收到监听事件===》"+event);
if (Event.KeeperState.SyncConnected == event.getState()) {
countDownLatch.countDown();
}
}
}
/**
* 获取锁
* @param id
*/
public void lock(Integer id) {
String path = "/xdclass-product-lock-" + id;
//创建临时节点,如果创建成功,就表示获取锁,如果失败则不断重试
try {
zooKeeper.create(path, "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
} catch (Exception e) {
while (true){
try {
Thread.sleep(500L);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
try {
zooKeeper.create(path, "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
} catch (Exception e1) {
continue;
}
break;
}
}
}
/**
* 释放锁
* @param id
*/
public void unLock(Integer id) {
String path = "/xdclass-product-lock-" + id;
try {
zooKeeper.delete(path, -1);
} catch (Exception e) {
e.printStackTrace();
}
}
private static class Singleton {
private static ZkLock instance;
static {
instance = new ZkLock();
}
private static ZkLock getInstance(){
return instance;
}
}
}
3、几个注意点:
(1) 原生api不支持递归创建节点
(2) 如果是单一应用,尽量不要使用分布式锁(可以使用原生的JDK锁,分布式锁消耗性能)