锁我们都知道是什么,在java中,提供了synchronized关键字,以及Lock接口,通过这两种形式,我们可以轻易的实现锁,但是这两种锁只能在单个JVM中 生效,而分布式锁就是能够在多个JVM中实现资源的竞争以及抢占。
为了在多个JVM中实现资源共享,我们需要引入一个第三方的一个中间件,分布式系统与这个中间件来交互,一次来实现分布式锁。
优点:实现简单,一般无需引入中间件
缺点:性能低,系统故障容易造成死锁
在redis中有很多有很多数据结构,其中string便有这个一个特性,setnx可以在key不存在的时候设置成功,通过 这个特性,我们便创建分布式锁setnx(key, value, expire);
优点:性能高,实现简单
缺点:超时时间不易设置,可能造成任务没执行完便因为锁超时导致锁被释放
org.apache.curator
curator-framework
5.3.0
org.apache.curator
curator-recipes
5.3.0
public class CuratorLockTest {
//定义锁节点的路径
private String node = "/locks";
//设置zookeeper连接
private final String connectString = "zookeeper1:2181,zookeeper2:2181,zookeeper3:2181";
//设置超时时间
private final int sessionTimeout = 2000;
//设置超时时间
private final int connectionTimeout = 3000;
public static void main(String[] args) {
new CuratorLockTest().test();
}
private void test() {
final InterProcessLock lock2 = new InterProcessMutex(getCuratorFramework(), node);
//线程2
new Thread(new Runnable() {
@Override
public void run() {
//线程加锁
try {
lock2.acquire();
System.out.println("线程2获取到锁");
//线程沉睡
Thread.sleep(5*1000);
lock2.release();
System.out.println("线程2释放锁");
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
//对分布式锁进行初始化
private CuratorFramework getCuratorFramework() {
//重试策略,定义初试时间3s,重试3次
ExponentialBackoffRetry exponentialBackoffRetry = new ExponentialBackoffRetry(3000, 3);
//初始化客户端
CuratorFramework client = CuratorFrameworkFactory.builder()
.connectString(connectString)
.sessionTimeoutMs(sessionTimeout)
.connectionTimeoutMs(connectionTimeout)
.retryPolicy(exponentialBackoffRetry)
.build();
//开启连接
client.start();
System.out.println("zookeeper 初始化完成...");
return client;
}
}@Slf4j
public class RedissonLockTest {
private final static String LOCK_KEY = "RESOURCE_KEY";
int n = 500;
public static void main(String[] args) {
}
public void lock() {
RedissonClient redissonClient = redissonClient();
//定义锁
RLock lock = redissonClient.getLock(LOCK_KEY);
lock.lock();
try {
log.info("线程:" + Thread.currentThread().getName() + "获得了锁");
log.info("剩余数量:{}", --n);
} catch (Exception e) {
log.error("程序执行异常:{}", e);
} finally {
log.info("线程:" + Thread.currentThread().getName() + "准备释放锁");
//释放锁
lock.unlock();
}
}
public void tryLock() {
RedissonClient redissonClient = redissonClient();
//定义锁
RLock lock = redissonClient.getLock(LOCK_KEY);
//lock.lock();
try {
//尝试加锁,最大等待时间300毫秒,上锁30毫秒自动解锁
if (lock.tryLock(300, 30, TimeUnit.MILLISECONDS)) {
log.info("线程:" + Thread.currentThread().getName() + "获得了锁");
log.info("剩余数量:{}", --n);
}
} catch (Exception e) {
log.error("程序执行异常:{}", e);
} finally {
log.info("线程:" + Thread.currentThread().getName() + "准备释放锁");
//释放锁
lock.unlock();
}
}
public static RedissonClient redissonClient() {
Config config = new Config();
config.useSingleServer().setAddress("redis://localhost:6379");
return Redisson.create(config);
}
} | 留言与评论(共有 0 条评论) “” |