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<String> 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> T listLPopByJson(String key, Class<T> 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<String> 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

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,667評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容