package com.my.utils;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;
public class ZookeeperLock {
private final static String ZOOKEEPER_ADDR = "127.0.0.1:2181";
private final static String lockPath = "/lockNode";
private final static int SESSION_TIMEOUT = 5000;
private ZkClient zkClient = new ZkClient(ZOOKEEPER_ADDR,SESSION_TIMEOUT);
private CountDownLatch countDownLatch = null;
public boolean tryLock() {
if (zkClient == null) {
return false;
}
try {
// zkClient.
zkClient.createEphemeral(lockPath);
} catch (Exception e) {
// e.printStackTrace();
return false;
}
return true;
}
public void getLock() {
String name = Thread.currentThread().getName();
if (tryLock()) {
System.out.println(name + ".....获取锁成功..... ");
} else {
System.out.println(name + ".....获取锁失败..... ");
/** 等待 **/
waitLock();
/** 递归 重新获取锁 **/
getLock();
}
}
public void unlock() {
if (zkClient != null) {
zkClient.delete(lockPath);
zkClient.close();
System.out.println(Thread.currentThread().getName() + "..成功解锁...");
return;
}
System.out.println("....解锁失败....");
}
public void waitLock() {
IZkDataListener listener = new IZkDataListener() {
@Override
public void handleDataChange(String dataPath, Object data) throws Exception {
}
@Override
public void handleDataDeleted(String dataPath) throws Exception {
/** 节点被删除时回调 **/
if (countDownLatch != null) {
countDownLatch.countDown();
}
}
};
zkClient.subscribeDataChanges(lockPath, listener);
/** 是否存在阻塞 **/
if (zkClient.exists(lockPath)) {
countDownLatch = new CountDownLatch(1);
try {
countDownLatch.await();
System.out.println(Thread.currentThread().getName() + "..等待获取获取锁...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
zkClient.unsubscribeDataChanges(lockPath,listener);
}
private static Integer count = 10;
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(20);
for (int i = 0; i < 20; i++) {
executor.execute(new Runnable() {
@Override
public void run() {
if (count <= 0) {
return;
}
ZookeeperLock zk = new ZookeeperLock();
zk.getLock();
if (count <= 0) {
System.err.printf(Thread.currentThread().getName() + "...抢购失败.." + "票剩余..." + (count) + "...张");
zk.unlock();
return;
}
System.err.printf(Thread.currentThread().getName() + "...抢购成功.." + "票剩余..." + (--count) + "...张");
zk.unlock();
}
});
}
}
}
依赖
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>