关于分布式锁网上相关博客有很多,坑也很多,还有一些写的天花乱坠。所以在此自己整理记录一下!先实现,再说原理。纯干货
所用环境
jdk1.8
tomcat8
IDEA
框架:ssh【ps:struts2集成一些东西真的很烦人,难度远比springMVC或者说springboot大!但是用熟之后也是可以的。】
上代码
pom.xml
这边我直接使用了目前最新的版本3.11.0,我看到有别人说根据自己的JDK环境选择版本,JDK1.8+选择3.5.4,JDK1.6+选择2.10.4.不过都更新到3.11.1了,毫不犹豫选择新的,有兼容性问题再说。显然我没有遇到因为兼容性问题导致的坑,哈哈。
<!-- 使用redisson依赖的jar包-->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.11.0</version>
</dependency>
redis相关properties配置文件
这里就展示关键几个参数了,
redis.url=127.0.0.1
redis.port= 6379
redis.password= password
.......
redisson配置代码
这里我是有自己的工具类去使用配置文件的信息,大家就八仙过海各显神通吧。这不是本文说的重点。
import org.redisson.Redisson;
import org.redisson.config.Config;
import sy.util.base.ConfigUtil;
public class RedissonManager {
private static Config config = new Config();
private static Redisson redisson = null;
static {
try {
String url = ConfigUtil.get("redis.url");
String port = ConfigUtil.get("redis.port");
String password = ConfigUtil.get("redis.password");
config.useSingleServer()
.setAddress("redis://"+url+":"+port)
.setPassword(password)
.setConnectionPoolSize(500);
redisson = (Redisson) Redisson.create(config);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Redisson getRedisson() {
return redisson;
}
}
分布式锁工具类
import org.redisson.Redisson;
import org.redisson.api.RLock;
import sy3.redisson.RedissonManager;
import java.util.concurrent.TimeUnit;
public class DistributedRedisLock {
//从配置类中获取redisson对象
private static Redisson redisson = RedissonManager.getRedisson();
private static final String LOCK_TITLE = "redisLock_";
//加锁
public static boolean acquire(String lockName){
//声明key对象
String key = LOCK_TITLE + lockName;
//获取锁对象
RLock mylock = redisson.getLock(key);
//加锁,并且设置锁过期时间,防止死锁的产生
mylock.lock(2, TimeUnit.MINUTES);
System.err.println("======lock======"+Thread.currentThread().getName());
//加锁成功
return true;
}
//锁的释放
public static void release(String lockName){
//必须是和加锁时的同一个key
String key = LOCK_TITLE + lockName;
//获取所对象
RLock mylock = redisson.getLock(key);
//释放锁(解锁)
mylock.unlock();
System.err.println("======unlock======"+Thread.currentThread().getName());
}
}
至此所有的配置就完成了
使用分布式锁
使用起来很简单,就像使用工具类一样就可以了,是不是灰常简单!
DistributedRedisLock.acquire("key");
//
这里写业务代码
//
DistributedRedisLock.release("key");
最后简单的介绍一下Redisson
Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务。其中包括(BitSet, Set, Multimap, SortedSet, Map, List, Queue, BlockingQueue, Deque, BlockingDeque, Semaphore, Lock, AtomicLong, CountDownLatch, Publish / Subscribe, Bloom filter, Remote service, Spring cache, Executor service, Live Object service, Scheduler service) Redisson提供了使用Redis的最简单和最便捷的方法。Redisson的宗旨是促进使用者对Redis的关注分离(Separation of Concern),从而让使用者能够将精力更集中地放在处理业务逻辑上。
你看看这是人说的话么 = =
在Redisson中,使用key来作为是否上锁的标志,当通过getLock(String key)方法获得相应的锁之后,这个key即作为一个锁存储到Redis集群中,在接下来如果有其他的线程尝试获取名为key的锁时,便会向集群中进行查询,如果能够查到这个锁并发现相应的value的值不为0,则表示已经有其他线程申请了这个锁同时还没有释放,则当前线程进入阻塞,否则由当前线程获取这个锁并将value值加一,如果是可重入锁的话,则当前线程每获得一个自身线程的锁,就将value的值加一,而每释放一个锁则将value值减一,直到减至0,完全释放这个锁。因为底层是基于分布式的Redis集群,所以Redisson实现了分布式的锁机制。
结束语
redis的部署方式有单节点部署、哨兵方式部署、集群方式部署3种方式,这3中方式都使用的是原生的redis;
本文展示的仅仅是单节点部署下的redis环境下Redisson的使用。如果有机会的话,会记录下其他部署方式下Redisson的使用。