redis实现秒杀

作者: z七夜 | 来源:发表于2018-05-10 22:26 被阅读212次

1.环境准备

eclipse + redis

2.具体实现

需求:某公司实现秒杀环节,100部手机(具体东西,自己设置)

2.1启动redis服务端

1.启动redis服务端(后台运行)

  1. 进入 DOS窗口

  2. 在进入redis的安装目录

  3. 输入:redis-server --service-install redis.windows.conf --loglevel verbose ( 安装redis服务 )

  4. 输入:redis-server --service-start ( 启动服务 )

  5. 输入:redis-server --service-stop

2.2做代码具体实现

入口类

public class MainController {
    
    public static void main(String[] args) {
        
         String key="shouji";
         int num=100;
        
        Jedis jedis = new Jedis("localhost");
        jedis.set(key, num+"");
        jedis.close();
        //创建一个线程池
        ExecutorService threadPool = Executors.newFixedThreadPool(20);
        //模拟一千个人同时访问
        for (int i =0; i < 1000; i++) {
//          new Run("user"+i,key,num)
            threadPool.execute(new Run("user"+i,key,num));
        }
        threadPool.shutdown();
    }
}

具体业务逻辑

public class Run implements Runnable{

    private String key;
    private String name;
    private int num;
    
    public Run(String name,String key,int num) {
        this.name = name;
        this.key = key;
        this.num = num;
    }
    
    Jedis jedis = new Jedis("localhost");
    @Override
    public void run() {
        //redis 监视一个key,当这个key的值发生改变时候,事务提交失败
        jedis.watch(key);
        String string = jedis.get(key);
        //得到商品的数量
        int currentnum = Integer.parseInt(string);
        if (currentnum <= num && currentnum >= 1) {
            //进行秒杀环节
            //开启事务
            Transaction multi = jedis.multi();
            //让商品减少一个
            multi.incrBy(key,-1);
            //提交事务.如果事务提交失败,返回值为空
            List<Object> exec = multi.exec();
            if (exec == null || exec.size()==0) {
                System.out.println(name+"----抢购失败!");
            }else {
                for (Object object : exec) {
                    System.out.println(name+"("+object.toString()+")"+"抢购商品成功,当前抢购成功人数为:"+(1-(currentnum-100)));
                }
            }
        }else {
            System.out.println("商品一已经被抢购完");
        }
        
    }

}

模拟一千个人同时抢购100部手机,使用redis做,redis是单线程操作,当事务被破坏时候,当前事务被破坏,达到多人抢购的效果

具体代码:码云https://gitee.com/zhangqiye/redis_second_kill/tree/master/Redis

也可加群共同探讨:552113611

欢迎各位指正
fd

相关文章

网友评论

  • 兔兔二号:感觉事务加的多此一举,redis本来就是原子性执行命令,直接incr -1获取返回值判断大小即可,不用get
    兔兔二号:@兔兔二号 watch就相当于乐观锁的版本控制嘛,不使用watch直接判断incr的返回值不就好啦😄
    z七夜:你好,加事务是为了模拟抢购失败,如果没有事务,每个先过来的请求都会执行减一,谁先来谁先得,但是这里面是你先来也会被别人打断因为上面进行了watch,当key变得时候,事务会执行失败,如有不同意见,欢迎指教

本文标题:redis实现秒杀

本文链接:https://www.haomeiwen.com/subject/iytxdftx.html