分布式阻塞锁
//1.获取一把锁,只要锁的名字一样,就是同一把锁 通过线程id判断
RLock lock = redisson.getLock("my-lock");
//2.加锁
lock.lock();//阻塞式等待 直到拿到锁
//只要占锁成功,就会启动一个定时任务【重新给锁设置过期时间,新的过期时间就是看门狗的默认时间】
try {
System.out.println("加锁成功,执行业务"+Thread.currentThread().getId());
}catch (Exception e){
} finally {
//调用解锁
System.out.println("释放锁...."+Thread.currentThread().getId());
lock.unlock();
}
读写锁
/**
* 读写锁,保证一定能读到最新数据,修改期间,写锁是一个排它锁(互斥锁),读锁是一个共享锁
* 写锁没释放。读锁就必须等到
* 写+读 ,等待写释放
* 写+写 阻塞方式,必须等上一个锁释放
* 读+写 只有读锁释放,写锁才能拿到锁
* @return
*/
@GetMapping("/writeValue")
@ResponseBody
public String writeValue(){
//获取锁
RReadWriteLock lock = redisson.getReadWriteLock("rw-lock");
RLock rLock = lock.writeLock();//拿到写锁
try {
//1.改数据加写锁,读数据加读锁
rLock.lock(); //加锁
String s = UUID.randomUUID().toString();
redisTemplate.opsForValue().set("writeValue",s);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
rLock.unlock();//解锁
}
return "s";
}
@GetMapping("/read")
@ResponseBody
public String readValue(){
//获取锁
RReadWriteLock lock = redisson.getReadWriteLock("rw-lock");
RLock rLock = lock.readLock();
rLock.lock();
try {
redisTemplate.opsForValue().get("writeValue");
} catch (Exception e) {
e.printStackTrace();
}finally {
rLock.unlock();
}
return "s";
}
计数锁
/**
*
*
* 计数锁,计数走位解锁
* @return
*/
@GetMapping
@ResponseBody
public String lockDoor() throws InterruptedException {
RCountDownLatch door = redisson.getCountDownLatch("door");
door.trySetCount(5);//等待五个方法走完
door.await();//等待闭锁都完成
return "放假了.....";
}
@GetMapping("/goGoGo/{id}")
public String goGoGo(@PathVariable("id")Long id){
RCountDownLatch door = redisson.getCountDownLatch("door");
door.countDown();//计数减一
return id+"班的人都走了";
}
信号量锁
/**
*信号量也可以限流
* @return
*/
@GetMapping("/park")
@ResponseBody
public String park() throws InterruptedException {
//获取信号量
RSemaphore park = redisson.getSemaphore("park");
// park.acquire();//获取一个信号 ,获取一个值 ,占一个位置
// true说明获取成功 有空位
boolean b = park.tryAcquire();
if (b){
//执行业务
}else {
return "error";
}
return "ok";
}
/**
*
* @return
*/
@GetMapping("/park")
@ResponseBody
public String go() throws InterruptedException {
//获取信号量
RSemaphore park = redisson.getSemaphore("park");
park.release();//释放一个信号 ,释放一个位置
return "ok";
}