分布式锁有很多用处,这里就不多说了,主要是程序,
实际呢也就是多线程访问zookeeper,只能由一个访问,利用临时节点的创建和删除来执行
这我没用纯zookeeper来实现,一是有问题,二不如curator好用简洁
首先导入jar包
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.14</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-client</artifactId>
<version>4.2.0</version>
</dependency>
上面四个jar包一个是zookeeper,剩下的是curator需要的
zookeeper分布式锁的程序
public class DistributedLock {
static final String CONNECT_ADDR = "192.168.137.131:2181"; //连接zookeeepr集群的一个节点IP:端口
static final int SESSION_OUTTIME = 5000;//超时时间,单位ms
InterProcessMutex lock = null;//实现了zookeeper分布式的公平可重入互斥锁
public DistributedLock() {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 10);//重试之间等待的时间,最大重试次数
//2 通过工厂创建连接
CuratorFramework cf = CuratorFrameworkFactory.builder()
.connectString(CONNECT_ADDR)
.sessionTimeoutMs(SESSION_OUTTIME)
.retryPolicy(retryPolicy)
.namespace("super") //父节点的名字,
//可以这么理解,如果加上,那创建节点删除的节点的父节点是他
.build();
//3 开启连接
cf.start();
//4 分布式锁
lock = new InterProcessMutex(cf, "/chrldren");//用于锁的节点
}
public void lock() {
try {
lock.acquire();//获取锁
} catch (Exception e) {
e.printStackTrace();
}
}
public void unlock() {
try {
lock.release();//释放锁
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
InterProcessMutex 的构造方法
// 最常用
public InterProcessMutex(CuratorFramework client, String path){
// Zookeeper利用path创建临时/永久(顺序)节点,实现公平锁的核心
this(client, path, new StandardLockInternalsDriver());
}
测试程序
public class LockTest {
DistributedLock lock = new DistributedLock();
int v = 0;
CountDownLatch latch = new CountDownLatch(30);//倒计时
public void test() throws InterruptedException {
for (int i = 0; i < 30; i++) {//开30个线程,争夺一个锁
new Thread(new Runnable() {
@Override
public void run() {
try {
lock.lock(); //加锁
for (int j = 0; j < 10000; j++) {
v++;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();//释放锁
latch.countDown();//倒计时减一
}
}
}).start();
}
latch.await();
System.out.println(v);
}
public static void main(String[] args) throws InterruptedException {
LockTest t = new LockTest();
t.test();
}
}
结果
上面创建的节点是永久节点,也可以设置临时节点,这里就不多说了,主要是实现用curator实现zookeeper的分布式锁
关于curator操作zookeeper的一些基础来和其他的介绍,可以来使用Curator操作ZooKeeper参考参考