大家应该都知道实现分布式锁的几种方式:
基于数据库实现分布式锁,
基于redis,
基于zookeeper
基于数据库实现分布式锁在高并发环境下性能太差,基于redis在锁时间限制和缓存一致性上存在不足。
这里介绍下基于zookeeper实现分布式锁
利用Apache封装好的curator包实现,curator-recipes和zookeeper版本要兼容,否则报UnimplementedException
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.0.1</version>
<exclusions>
<exclusion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.13</version>
</dependency>
package com;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.retry.ExponentialBackoffRetry;
import java.io.Serializable;
/**
* 分布式锁
* @author
*/
public class DistributeLockService implements Serializable {
private CuratorFramework client;
public static volatile DistributeLockService instance;
private DistributeLockService() {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
client = CuratorFrameworkFactory.newClient("192.168.1.170:2181", retryPolicy);
client.start();
}
public static DistributeLockService getInstance() {
if (instance == null) {
System.out.println("instance is null");
synchronized (DistributeLockService.class) {
if (instance == null) {
instance = new DistributeLockService();
}
}
} else {
System.out.println("instance is not null");
}
return instance;
}
public InterProcessMutex acquire(String path){
InterProcessMutex mutex = new InterProcessMutex(client, path);
try {
mutex.acquire();
System.out.println(Thread.currentThread().getName() + ";获得了锁");
return mutex;
} catch (Exception e) {
e.printStackTrace();
System.out.println(Thread.currentThread().getName() + ";获取锁失败" + e);
}
return null;
}
public void release(InterProcessMutex mutex) {
try {
if (mutex != null) {
mutex.release();
}
System.out.println(Thread.currentThread().getName() + ";释放了锁");
} catch (Exception e) {
e.printStackTrace();
System.out.println(Thread.currentThread().getName() + ";释放锁失败" + e);
}
}
}
测试代码
package com;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
public class TestLock {
public static void update(String name) {
String path = "/lock/xiaoming/" + name;
DistributeLockService distributeLockService = DistributeLockService.getInstance();
InterProcessMutex mutex = distributeLockService.acquire(path);
if (mutex != null) {
try {
distributeLockService.release(mutex);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
String name = "testLock";
Thread thread1 = new Thread(() -> update(name));
Thread thread2 = new Thread(() -> update(name));
thread1.start();
thread2.start();
}
}
测试结果