Redis使用list队列做商品秒杀

本代码是基于redis的list做秒杀系统:

基于Spring:

package com.intramirror.image.search;
import com.google.common.collect.Lists;
import com.intramirror.image.search.cache.RedisService;
import com.intramirror.image.search.controller.TestController;
import com.intramirror.image.search.service.TestService;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.PostConstruct;
import javax.annotation.Resource; 
import java.util.List;
import java.util.UUID;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;


@RunWith(SpringRunner.class)
@SpringBootTest
public class ImageSearchWebApplicationTests {
     @Autowired
     private TestService testService;
     @Autowired
     private RedisService redisService;

     ExecutorService executorService = null;

    @Before
    public void init() {
        List list = Lists.newArrayListWithCapacity(100);
        for (int i = 0; i < 100; i++) {
            list.add("1");
        }
       //模拟商品Id和库存
       redisService.listRPushByJson("5", list, 1000);
        executorService = Executors.newFixedThreadPool(800);
    }

    @Test
    public void contextLoads() {
        AtomicInteger successNum = new AtomicInteger(0);
        AtomicInteger failNum = new AtomicInteger(0);
        CountDownLatch countDownLatch = new CountDownLatch(800);
        CyclicBarrier cyclicBarrier = new CyclicBarrier(800);
        for (int i = 0; i < 800; i++) {
            executorService.execute(() -> {
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException | BrokenBarrierException e) {
                    e.printStackTrace();
                }
                if (redisService.listLPopByJson("5", String.class) != null) {
                    System.out.println("成功的线程name: " + Thread.currentThread().getName());
                    successNum.getAndIncrement();
                } else {
                    failNum.getAndIncrement();
                }
                countDownLatch.countDown();
            });
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("下单成功:" + successNum.get());
        System.out.println("下单失败:" + failNum.get());
    }
}

Redis操作:

/**
   * list lPop(json序列化)
   *
   * @param key 缓存key
   * @return object
   */
  public  T listLPopByJson(String key, Class clazz) {
      try {
          String valueStr = stringRedisTemplate.opsForList().leftPop(key);
          if (StringUtils.isBlank(valueStr)) {
              return null;
          }
          return JSON.parseObject(valueStr, clazz);
      } catch (Exception e) {
          log.error("listLPopByJson error key:{}", key, e);
          return null;
      }
  }


  /**
   * list rPush(json序列化)
   *
   * @param key 缓存key
   * @param valueList 需要缓存value集合
   * @param expiredSeconds 过期时间(单位为秒)
   */
  public void listRPushByJson(String key, List valueList, long expiredSeconds) {
      if (StringUtils.isBlank(key) || CollectionUtils.isEmpty(valueList)) {
          return;
      }
      try {
          List jsonValueList = valueList.stream().map(JSON::toJSONString).collect(Collectors.toList());
          stringRedisTemplate.opsForList().rightPushAll(key, jsonValueList);
          stringRedisTemplate.expire(key, expiredSeconds, TimeUnit.SECONDS);
      } catch (Exception e) {
          log.error("listRPushByJson error key:{} valueList:{} expired:{}", key, valueList, expiredSeconds, e);
      }
  }  
跑一下结果:

成功的线程name: pool-3-thread-544
成功的线程name: pool-3-thread-93
成功的线程name: pool-3-thread-61
成功的线程name: pool-3-thread-69
成功的线程name: pool-3-thread-132
成功的线程name: pool-3-thread-140
成功的线程name: pool-3-thread-68
成功的线程name: pool-3-thread-57
成功的线程name: pool-3-thread-64
成功的线程name: pool-3-thread-49
成功的线程name: pool-3-thread-65
成功的线程name: pool-3-thread-43
成功的线程name: pool-3-thread-71
成功的线程name: pool-3-thread-23
成功的线程name: pool-3-thread-77
成功的线程name: pool-3-thread-157
成功的线程name: pool-3-thread-144
成功的线程name: pool-3-thread-76
成功的线程name: pool-3-thread-148
成功的线程name: pool-3-thread-52
成功的线程name: pool-3-thread-84
成功的线程name: pool-3-thread-168
成功的线程name: pool-3-thread-53
成功的线程name: pool-3-thread-181
成功的线程name: pool-3-thread-91
成功的线程name: pool-3-thread-155
成功的线程name: pool-3-thread-87
成功的线程name: pool-3-thread-35
成功的线程name: pool-3-thread-39
成功的线程name: pool-3-thread-47
成功的线程name: pool-3-thread-51
成功的线程name: pool-3-thread-179
成功的线程name: pool-3-thread-95
成功的线程name: pool-3-thread-55
成功的线程name: pool-3-thread-92
成功的线程name: pool-3-thread-30
成功的线程name: pool-3-thread-134
成功的线程name: pool-3-thread-88
成功的线程name: pool-3-thread-62
成功的线程name: pool-3-thread-142
成功的线程name: pool-3-thread-146
成功的线程name: pool-3-thread-154
成功的线程name: pool-3-thread-158
成功的线程name: pool-3-thread-162
成功的线程name: pool-3-thread-166
成功的线程name: pool-3-thread-170
成功的线程name: pool-3-thread-90
成功的线程name: pool-3-thread-182
成功的线程name: pool-3-thread-66
成功的线程name: pool-3-thread-26
成功的线程name: pool-3-thread-54
成功的线程name: pool-3-thread-46
成功的线程name: pool-3-thread-86
成功的线程name: pool-3-thread-50
成功的线程name: pool-3-thread-74
成功的线程name: pool-3-thread-70
成功的线程name: pool-3-thread-82
成功的线程name: pool-3-thread-42
成功的线程name: pool-3-thread-38
成功的线程name: pool-3-thread-34
成功的线程name: pool-3-thread-22
成功的线程name: pool-3-thread-18
成功的线程name: pool-3-thread-14
成功的线程name: pool-3-thread-10
成功的线程name: pool-3-thread-6
成功的线程name: pool-3-thread-2
成功的线程name: pool-3-thread-27
成功的线程name: pool-3-thread-32
成功的线程name: pool-3-thread-36
成功的线程name: pool-3-thread-48
成功的线程name: pool-3-thread-63
成功的线程name: pool-3-thread-15
成功的线程name: pool-3-thread-59
成功的线程name: pool-3-thread-19
成功的线程name: pool-3-thread-11
成功的线程name: pool-3-thread-7
成功的线程name: pool-3-thread-3
成功的线程name: pool-3-thread-85
成功的线程name: pool-3-thread-45
成功的线程name: pool-3-thread-33
成功的线程name: pool-3-thread-41
成功的线程name: pool-3-thread-37
成功的线程name: pool-3-thread-29
成功的线程name: pool-3-thread-25
成功的线程name: pool-3-thread-21
成功的线程name: pool-3-thread-17
成功的线程name: pool-3-thread-13
成功的线程name: pool-3-thread-9
成功的线程name: pool-3-thread-5
成功的线程name: pool-3-thread-40
成功的线程name: pool-3-thread-44
成功的线程name: pool-3-thread-60
成功的线程name: pool-3-thread-20
成功的线程name: pool-3-thread-56
成功的线程name: pool-3-thread-24
成功的线程name: pool-3-thread-16
成功的线程name: pool-3-thread-12
成功的线程name: pool-3-thread-8
成功的线程name: pool-3-thread-4
成功的线程name: pool-3-thread-1
下单成功:100
下单失败:700


库存大小改为10以后:
成功的线程name: pool-3-thread-159
成功的线程name: pool-3-thread-160
成功的线程name: pool-3-thread-167
成功的线程name: pool-3-thread-164
成功的线程name: pool-3-thread-106
成功的线程name: pool-3-thread-154
成功的线程name: pool-3-thread-166
成功的线程name: pool-3-thread-162
成功的线程name: pool-3-thread-538
成功的线程name: pool-3-thread-163
下单成功:10
下单失败:790

你可能感兴趣的:(Redis使用list队列做商品秒杀)