synchronized 控制并发(活动秒杀)
Posted zhonglihai
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了synchronized 控制并发(活动秒杀)相关的知识,希望对你有一定的参考价值。
1.首先我们新建一个Controller用于秒杀:
package com.imooc.Controller; import com.imooc.service.impl.SeckillServiceImpl; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * Created by zhongliahi on 2018/6/11. * 秒杀测试 */ @RestController @RequestMapping(value = "/skill") @Slf4j public class SeckillController { @Autowired private SeckillServiceImpl seckillService; //@PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中 // URL 中的 {xxx} 占位符可以通过@PathVariable(“xxx“) 绑定到操作方法的入参中。 @GetMapping(value = "/query/{productId}") public String query(@PathVariable String productId) throws Exception{ return seckillService.querySeckillProductInfo(productId); } @GetMapping("/order/{productId}") public String skill(@PathVariable String productId) throws Exception{ log.info("秒杀----productId:"+productId); seckillService.orderProductMockDiffUser(productId); return seckillService.querySeckillProductInfo(productId); } }
2.建立一个Service
package com.imooc.service; /** * Created by zhongliahi on 2018/6/11. */ public interface SeckillService { String queryMap(String productId); String querySeckillProductInfo(String productId); void orderProductMockDiffUser(String productId); }
3.实现Service
package com.imooc.service.impl; import com.imooc.Exception.SellException; import com.imooc.enums.ExceptionEnum; import com.imooc.service.SeckillService; import com.imooc.util.KeyUtils; import org.springframework.stereotype.Service; import java.util.HashMap; import java.util.Map; /** * Created by zhonglihai on 2018/6/11. * 秒杀Serviceimpl * 演示 */ @Service public class SeckillServiceImpl implements SeckillService { /** * 秒杀特价 1000000份 * @param productId * @return */ static Map<String,Integer> products; static Map<String,Integer> stock; static Map<String,String> orders; static{ /** * ,模拟多个表,商品信息表,库存表,秒杀成功订单表 */ products =new HashMap<>(); stock=new HashMap<>(); orders=new HashMap<>(); products.put("123",1000000); stock.put("123",1000000); } @Override public String queryMap(String productId) { return "活动特价,限量:"+products.get(productId)+",还剩:"+stock.get(productId) +"份"+",成功下单用户数:"+orders.size()+"人。"; } @Override public String querySeckillProductInfo(String productId) { return this.queryMap(productId); } /** * 主要秒杀的逻辑 * @param productId */ @Override public synchronized void orderProductMockDiffUser(String productId) { //查询该商品库存,为0则活动结束 int stockNum=stock.get(productId); if(stockNum==0){ throw new SellException(ExceptionEnum.SECKILL_OVER); }else{ //2.下单(模拟不同用户opendid不同) orders.put(KeyUtils.getUniqueKey(),productId); //3.减库存 stockNum=stockNum-1; try{ Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } stock.put(productId,stockNum); } } }
关于压测:
压力测试是一种基本的质量保证行为,在秒杀活动中更为重要,防止超卖(卖出去的比库存的多)、少卖(有买了但是没卖),目前主流的工具与Jmeter、LoadRunner等,老一点的有apache ab等,正好本人机器装有Apace服务,因此使用apache 做压测。
以上是关于synchronized 控制并发(活动秒杀)的主要内容,如果未能解决你的问题,请参考以下文章