1.前言
由于水平有限,总觉得哪里怪怪的。还请高手批评指正。
2.核心思想
当redis中,有这个key的时候,就认为已经有了锁;业务处理完后,清除redis中key,即认为清除了释放锁。
3.主要应用场景
当两个客户端同时操作一个资源时,客户端1需要审批该资源;客户端2需要撤回该资源。
4.关键源码所示
a)RedisLock.java
package com.wayne.demo.lock;
import com.wayne.demo.dao.RedisDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
public class RedisLock implements Lock {
@Autowired
private RedisDao redisDao;
//标识当前key有没有被上锁
private static Map<String,Boolean> lockedMap = new HashMap<>();
@Override
public boolean tryLock(String key) {
synchronized (key){
Object o = redisDao.get(0, key);
if(null != o){
return false;
}else{
return true;
}
}
}
@Override
public void lock(String key) {
synchronized (key){
redisDao.save(0,key,key);
lockedMap.put(key,true);
}
}
@Override
public void unlock(String key) {
synchronized (key){
redisDao.removeData(0,key);
lockedMap.put(key,false);
lockedMap.remove(key);
}
}
@Override
public boolean isLocked(String key) {
return lockedMap.get(key) == null?false:lockedMap.get(key);
}
}
b)ThreadController.java
package com.wayne.demo.comtrollor;
import com.wayne.demo.lock.RedisLock;
import com.wayne.demo.params.BaseParams;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.concurrent.TimeUnit;
@Slf4j
@RestController
@RequestMapping("/threadController")
public class ThreadController {
private static Logger logger = LoggerFactory.getLogger(ThreadController.class);
@Autowired
private RedisLock redisLock;
@PostMapping("/submitApproval")
void submitApproval(@RequestBody BaseParams params){
logger.info("某个线程提交了审核");
logger.info("我开始处理审核");
if(!redisLock.isLocked(params.getKey())){
logger.info("其他资源没有占用");
logger.info("我开始处理审核");
redisLock.lock(params.getKey());
try {
TimeUnit.MINUTES.sleep(10);
}catch (InterruptedException e){
e.printStackTrace();
} finally {
redisLock.unlock(params.getKey());
}
}else{
logger.info("其他资源正在处理");
logger.info("我无法处理审核");
}
}
@PostMapping("/cancelAppral")
void cancelAppral(@RequestBody BaseParams params){
logger.info("某个线程撤销了审核");
if(!redisLock.isLocked(params.getKey())){
logger.info("其他资源没有占用");
logger.info("我开始处理撤销了审核");
redisLock.lock(params.getKey());
try {
TimeUnit.MINUTES.sleep(5);
}catch (InterruptedException e){
e.printStackTrace();
} finally {
redisLock.unlock(params.getKey());
}
}else{
logger.info("其他资源正在处理");
logger.info("我无法处理撤销了审核");
}
}
}
5.测试结果