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 做压测。

  

原文地址:https://www.cnblogs.com/zhonglihai/p/9167120.html

时间: 2024-10-31 19:29:14

synchronized 控制并发(活动秒杀)的相关文章

【总结】瞬时高并发(秒杀/活动)Redis方案(转)

转载地址:http://bradyzhu.iteye.com/blog/2270698 1,Redis 丰富的数据结构(Data Structures) 字符串(String) Redis字符串能包含任意类型的数据 一个字符串类型的值最多能存储512M字节的内容 利用INCR命令簇(INCR, DECR, INCRBY)来把字符串当作原子计数器使用 使用APPEND命令在字符串后添加内容 列表(List) Redis列表是简单的字符串列表,按照插入顺序排序 你可以添加一个元素到列表的头部(左边:

如何解决高并发,秒杀问题

相信不少人会被这个问题困扰,分享大家一篇这样的文章,希望能够帮到你! 一.秒杀业务为什么难做?1)im系统,例如qq或者微博,每个人都读自己的数据(好友列表.群列表.个人信息):2)微博系统,每个人读你关注的人的数据,一个人读多个人的数据:3)秒杀系统,库存只有一份,所有人会在集中的时间读和写这些数据,多个人读一个数据. 例如:小米手机每周二的秒杀,可能手机只有1万部,但瞬时进入的流量可能是几百几千万. 又例如:12306抢票,票是有限的,库存一份,瞬时流量非常多,都读相同的库存.读写冲突,锁非

关于高并发和秒杀系统,你知道的和不知道的一些事

这篇文章也算是对于课程 <PHP秒杀系统 高并发高性能的极致挑战> 的一个整理,视频之外的另外一种形式吧. 大家也许开发过高并发的系统或者秒杀程序,但肯定都有接触过,像电商平台的秒杀.抢购等活动,还有12306春运抢票. 互联网公司,做一些有奖活动,而且数量有限,奖品给力,如果是先到先得的策略,那就类似秒杀系统了. 这类系统最大的问题就是活动周期短,瞬间流量大(高并发),很少人可以成功下单,绝大多数人都是很遗憾.所以从运营体验上,没有成功下单的人,心里肯定是不好受的,如果这时候,因为技术.网络

java并发编程学习:用 Semaphore (信号量)控制并发资源

并发编程这方面以前关注得比较少,恶补一下,推荐一个好的网站:并发编程网 - ifeve.com,上面全是各种大牛原创或编译的并发编程文章. 今天先来学习Semaphore(信号量),字面上看,根本不知道这东西是干啥的,借用 并发工具类(三)控制并发线程数的Semaphore一文中的交通红绿信号灯的例子来理解一下: 一条4车道的主干道,假设100米长,每辆车假设占用的长度为10米(考虑到前后车距),也就是说这条道上满负载运行的话,最多只能容纳4*(100/10)=40辆车,如果有120辆车要通过的

【nodejs爬虫】使用async控制并发写一个小说爬虫

最近在做一个书城项目,数据用爬虫爬取,百度了一下找到这个网站,以择天记这本小说为例. 爬虫用到了几个模块,cheerio,superagent,async. superagent是一个http请求模块,详情可参考链接. cheerio是一个有着jQuery类似语法的文档解析模块,你可以简单理解为nodejs中的jQuery. async是一个异步流程控制模块,在这里我们主要用到async的mapLimit(coll, limit, iteratee, callback) async.mapLim

多线程小记,线程控制并发

private AutoResetEvent exitEvent; private void ProcessA() { while (true) { Console.WriteLine("do some thing"); if (exitEvent.WaitOne(waitTime)) { break; } } Console.WriteLine("exit"); } exitEvent.Set(); private void ProcessB() { while

(转)电商网站50W-100W高并发,秒杀功能是怎么实现的?

电商网站50W-100W高并发,秒杀功能是怎么实现的? 在淘宝.天猫.京东等国内大型电商平台“造节”的带领下,国内各电商平台纷纷跟进,双十一.双十二.618等电商专属节日也吸引了大量的用户参与.节前生意惨淡.访客寥寥,节日当天流量增长却异常迅猛,这对于广大程序猿同学和运维人员来说,无疑是巨大的考验. 秒杀系统的流量虽然很高,但是实际有效流量比较小:利用系统的层次结构,在每个阶段提前校验,拦截无效流量,可以减少大量无效流量涌入数据库,从而保障业务系统的正常运行: 第一步:利用浏览器缓存和CDN加速

PHP高并发商城秒杀

1.什么是秒杀 秒杀活动是一些购物平台推出的集中人气的活动,一般商品数量很少,价格很便宜,限定开始购买的时间,会在以秒为单位的时间内被购买一空.比如原价千元甚至万元的商品以一元的价格出售,但数量只有一件,在某天的某个时间开始出售,这就造成很多人去抢这一件商品.当然想抢到是需要很多因素的,比如你的电脑配置.网速,还有你的运气. 2.秒杀会带来的问题 (1).高并发 比较火热的秒杀在线人数都是10w起的,如此之高的在线人数对于网站架构从前到后都是一种考验. (2).超卖 任何商品都会有数量上限,如何

Spring Boot项目之synchronized处理并发

在orderProductMockDiffUser(String productId)方法体上加入synchronized关键字,可以保证每次都是单线程处理,因为加上了锁.但这种做法只适合单点操作,即单机上的做法,对于多机上来说的话是不合适的. package com.imooc.controller; import com.imooc.service.SecKillService;import lombok.extern.slf4j.Slf4j;import org.springframewo