一、背景说明
随着互联网的进步和推广,高并发几乎是所有系统面临的问题,某些接口需要涉及同步线程处理,而这类接口在面临着高并发的请求冲击下,有请求进入排队时,请求是怎么处理的呢?
二、问题案例
springmvc+mybatis框架现在成为时下最流行的后端架构框架,controller接收request请求,调用service的业务处理逻辑,最后返回响应。
设想当高并发请求抢占某些有限资源,则需要在业务处理的逻辑层面通过线程同步synchronized来处理,假设请求1秒钟来一个,而线程同步逻辑处理层需要6秒钟。那么回出现什么情况呢,直接上代码,用结果说明。
spring的所有controller默认都是单例,消费VIP接口在处理逻辑上类似于秒杀,为防止
1.获取request请求controller
@Controller
@RequestMapping("/common")
public class CommonController{
@Autowired
CommonService commonService;
private static int requestNum = 1;//成员变量记录请求序列号(因为spring中所有的controller在容器中默认都是单例singleton模式,该类和成员变量都是JVM中存在唯一一份的代代码片段二进制码)
/**
* 消费VIPCode
*/
@RequestMapping(value="/useVipCode",method=RequestMethod.POST)
@ResponseBody
public Map<String, Object> useVipCode(HttpServletRequest request, HttpServletResponse response){
response.setHeader("Access-Control-Allow-Origin","*");
Map<String, Object> map = new HashMap<String, Object>();
String vipCode = request.getParameter("vipCode");
//调用业务逻辑层
int currentRequestNum = requestNum;
requestNum ++;
return commonService.UseVipCode(vipCode,currentRequestNum);
}
}
}
2.业务处理层service
@Service("commonService")
public class CommonService {
/**
* 使用VIPCode码
*/
public synchronized Map<String,Object> UseVipCode1(String vipCode,int currentRequestNum){
//使用线程同步来防止多线程抢占资源
Map<String,Object> map = new HashMap<String, Object>();
//查询VIPCode信息
//根据VIPCode信息计算每一项的到期日期并且开通权限
//调用使用VIPCode的接口
System.out.println("【正在处理请求:"+currentRequestNum+"】VIPCode:"+vipCode);
try {
Thread.currentThread().sleep(6000);