审批服务单节点版本的锁改造
1.思路描述:
- 模仿redis的锁机制,使用代理模式和Future类构件高性能缓存
- 使用简单工厂模式生产各种类的审批处理操作
- 将原先的变量锁优化,避免了代码锁的使用,提高并发能力
2.代码示例
抽象的审批入参
ApprovalOperationEntity.java
/**
* @author sijiachang
* @date 2021/4/22 0022 18:32
* @Description: 审批操作传入的参数
*/
@Data
public class ApprovalOperationEntity {
public String businessId;
public String approvalType;
public Object other;
}
创建审批操作的父接口ApprovalParentI.java
public interface ApprovalParentI<V> {
V approval(ApprovalOperationEntity param) throws Exception;
}
创建两种实现
ApprovalAgreeOperation.java
@Component
public class ApprovalAgreeOperation implements ApprovalParentI {
@Override
public Object approval(ApprovalOperationEntity param) throws Exception {
Thread.sleep(1000);
return "审批同意";
}
}
ApprovalDisagreeOperation.java
@Component
public class ApprovalDisagreeOperation implements ApprovalParentI {
@Override
public Object approval(ApprovalOperationEntity param) throws Exception {
Thread.sleep(1000);
return "审批不同意";
}
}
使用代理模式,对审批的具体操作进行并发的安全
ConcurrentApprovalOperation.java
@Component
public class ConcurrentApprovalOperation<V> implements ApprovalParentI<V> {
/* 使用ConcurrentHashMap做缓存的数据结构,避免锁的使用 */
private final ConcurrentHashMap<String, Future<V>> sharedMap = new ConcurrentHashMap<String, Future<V>>();
/* 审批操作的真正业务实现 */
private ApprovalParentI<V> approval;
ConcurrentApprovalOperation() {
}
static class AgainTimes {
public static final ThreadLocal<Integer> times = new ThreadLocal<Integer>() {
@Override
protected Integer initialValue() {
return new Integer(3);
}
};
}
public void initApprovalParentI(ApprovalParentI<V> approval) {
this.approval = approval;
}
public V approval(ApprovalOperationEntity param) throws Exception {
String key = param.getBusinessId();
while (true) {
Future<V> future = sharedMap.get(key);
if (future == null) {
FutureTask<V> operation = new FutureTask<V>(() -> {
return approval.approval(param);
});
Future<V> operation2 = sharedMap.putIfAbsent(key, operation);
if (operation2 == null) {
operation.run();
return operation.get();
} else {
checkTimes();
}
} else {
checkTimes();
}
}
}
private void checkTimes() throws Exception {
if (AgainTimes.times.get() <= 0) {//重置循环次数,并抛出异常
AgainTimes.times.set(3);
throw new Exception();
} else {//减少循环次数
AgainTimes.times.set(AgainTimes.times.get() - 1);
Thread.sleep(500);
}
}
}
构建简单工厂生产具体审批处理
ApprovalOperationFactory .java
@Component
public class ApprovalOperationFactory {
// 一个有趣的问题是,我并不确定这样能注入进来
@Autowired
private ApprovalAgreeOperation agreeOperation;
@Autowired
private ApprovalDisagreeOperation disagreeOperation;
private static final String APPROVALTYPE_AGREE = "agree";
private static final String DISAPPROVALTYPE_AGREE = "disagree";
public ApprovalParentI createApprovalOperation(String approvalType){
if(APPROVALTYPE_AGREE.equals(approvalType)){
return this.agreeOperation;
}else if(DISAPPROVALTYPE_AGREE.equals(approvalType)){
return this.disagreeOperation;
}else {
return null;
}
}
}
审批service层简化
@Service
public class ApprovalService {
@Autowired
private ApprovalOperationFactory approvalOperationFactory;
@Autowired
private ConcurrentApprovalOperation concurrentApprovalOperation;
public Object executiveApproval(ApprovalOperationEntity param){
ApprovalParentI approvalOperation = approvalOperationFactory.createApprovalOperation(param.getApprovalType());
concurrentApprovalOperation.initApprovalParentI(approvalOperation);
try {
return concurrentApprovalOperation.approval(param);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
后续自测结束再优化
本文不涉及公司代码逻辑,仅是本人抽象后的代码块