Redisson实现的分布式锁的简单实用
类型
- 普通锁
这种锁通过Rlock.getLock()即可使用,一旦某个线程获取到这个锁,那么其他竞争这个锁的线程就必须等待,直到这个所释放为止。我们使用一个实例证明这一点。
创建一个线程池
ThreadPoolExecutor executor = new ThreadPoolExecutor(100, 1000,
1, TimeUnit.SECONDS,new LinkedBlockingDeque<>(100));
(1) 使用一个线程去获取锁,然后锁定。
executor.execute(() -> {
Config config = new Config();
config.useSingleServer().setAddress(SERVER_ADDRESS);
RedissonClient client = Redisson.create(config);
//他的锁是用一个hash值作为锁的,使用ttl观察这个锁的变化发现,生命时间到20的时候回自动变为30,循环变化,key就一直被锁住了
//RLock rLock = client.getLock("bond");//这步骤只是创建了一个RLock对象,并非执行了获取锁的操作
RLock rLock = client.getLock("bond");//这步骤只是创建了一个RLock对象,并非执行了获取锁的操作
//isLocked()观察这把锁是否被任何的线程锁住,逻辑就是如果这个锁存在就是被人锁住了,否则就不是被锁住的
//执行获取锁的操作,如果所已经被其他线程持有的话,这里就需要等待,否则获取成功锁,执行后面的逻辑
//rLock.lock();//上锁,这个步骤会在redis中产生一个hash值,也就是锁,这是一个阻塞操作,会一直阻塞到锁的释放
rLock.lock(3, TimeUnit.SECONDS);//上一个带有超时特性的锁,
System.out.println("获取到锁:" + rLock.isLocked());
});
(2)使用另外一组线程去获取锁,观察结果看是否能够锁定数据,如果不能获取到锁,那么线程是会被阻塞执行的。
//这里将会产生许多等待的线程,当锁放开之后大约10s左右会有下一个线程获得锁
for (int i = 0; i < 10; i++) {
executor.execute(() -> {
Config config = new Config();
config.useSingleServer().setAddress(SERVER_ADDRESS);
RedissonClient client = Redisson.create(config);
//他的锁是用一个hash值作为锁的,获取一个公平锁
RLock rLock = client.getLock("bond");
//rLock.lock();//执行获取锁的操作,如果所已经被其他线程持有的话,这里就需要等待,否则获取成功锁,执行后面的逻辑
rLock.lock(3, TimeUnit.SECONDS);//上一个带有超时特性的锁
System.out.println(Thread.currentThread().getName() + " 获取到锁");
});
}
(3)也可以使用rLock.lock()的方式,然后在redis的cli中删除锁来释放锁,观察结果即可得到答案。