【一】介绍
分布式锁简介:
1.1 什么是锁
在单机环境下,当存在多个线程可以同时改变某个共享变量时,就需要同步来实现该功能,使其线程安全。
而同步就是通过锁来实现的。锁保证了同一时刻只有一个线程来修改共享变量。
在单机环境下,Java提供了一些并发安全包可以一定程度上保证线程安全,但是在分布式环境(多机环境)下,这些并发包显得就无能为力了!!
1.2 什么是分布式
分布式的CAP理论:
任何一个分布式系统都无法同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance),最多只能同时满足两项。
目前很多大型网站及应用都是分布式部署的,分布式场景中的数据一致性问题一直是一个比较重要的话题。基于 CAP理论,很多系统在设计之初就要对这三者做出取舍。在互联网领域的绝大多数的场景中,都需要牺牲强一致性来换取系统的高可用性,系统往往只需要保证最终一致性。
3、什么是分布式锁
顾名思义,分布式锁肯定是用在分布式环境下。在分布式环境下,使用分布式锁的目的也是保证同一时刻只有一个线程来修改共享变量,修改共享缓存……。
1.3 分布式锁特性
1、在分布式系统环境下,一个方法在同一时间只能被一个机器的一个线程执行;
2、高可用的获取锁与释放锁;
3、高性能的获取锁与释放锁;
4、具备可重入特性;
5、具备锁失效机制,防止死锁;
6、具备非阻塞锁特性,即没有获取到锁将直接返回获取锁失败
【二】curator介绍
- public void acquire();//获取锁
- public boolean acquire(long time, TimeUnit unit);//获取锁,可以指定阻塞时间
- public void release();//释放锁
- boolean isAcquiredInThisProcess();//判断当前是否持有锁,实际使用中,如果持有锁,可以进行锁的释放
实现类:
InterProcessMultiLock 将多个锁作为单个实体管理的容器
InterProcessMutex 分布式可重入排它锁
InterProcessReadWriteLock 分布式读写锁
InterProcessSemaphoreMutex 分布式排它锁
InterProcessSemaphoreV2 信号量
【三】代码实现
package com.provider.demo.comment;
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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.TimeUnit;
/**
* @Description
* @Author fengwen
* @Date 2020/1/22 18:12
* @Version V1.0
*/
public class DistributedLock {
public static Logger log = LoggerFactory.getLogger(DistributedLock.class);
//可重入排它锁
private InterProcessMutex interProcessMutex;
//竞争资源标志
private String lockName;
//根节点
private String root = "/distributed/lock/";
private static CuratorFramework curatorFramework;
private static String ZK_URL = "127.0.0.1:2181";
static{
curatorFramework= CuratorFrameworkFactory.newClient(ZK_URL,new ExponentialBackoffRetry(1000,3));
curatorFramework.start();
}
/**
* 实例化
* @param lockName
*/
public DistributedLock(String lockName){
try {
this.lockName = lockName;
interProcessMutex = new InterProcessMutex(curatorFramework, root + lockName);
}catch (Exception e){
log.error("initial InterProcessMutex exception="+e);
}
}
/**
* 获取锁
*/
public void acquireLock(){
try {
//重试2次,每次最大等待2s,也就是最大等待4s
while (true){
boolean acquire = interProcessMutex.acquire(2, TimeUnit.SECONDS);
if (acquire){
log.info("Thread:"+Thread.currentThread().getId()+" acquire distributed lock success");
break;
}
}
} catch (Exception e) {
log.error("distributed lock acquire exception="+e);
}
}
/**
* 释放锁
*/
public void releaseLock(){
try {
if(interProcessMutex != null && interProcessMutex.isAcquiredInThisProcess()){
interProcessMutex.release();
curatorFramework.delete().inBackground().forPath(root+lockName);
log.info("Thread:"+Thread.currentThread().getId()+" release distributed lock success");
}
}catch (Exception e){
log.info("Thread:"+Thread.currentThread().getId()+" release distributed lock exception="+e);
}
}
}