分別開啓15和20個線程模擬秒殺,操作redis事務,商品居然賣不完。。

用 ExecutorService executor = Executors.newFixedThreadPool(15);創建線程池,分別模擬1000個用戶去搶100個商品,線程池超過15個之後,商品居然秒殺不完? 兩個類

package redis;

import java.util.List;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

public class SaleRunable implements Runnable {

    String productKey = "iphone8";//監視的key 當前秒殺商品的數量
    Jedis jedis = new Jedis("192.168.17.128");
    String userName;

    public SaleRunable(String userName) {
        this.userName = userName;
    }

    @Override
    public void run() {
        //商品的key  , 秒殺有個數量
        //watch 監視一個key,當事務執行之前這個key發生了改變,事務會被打斷
        jedis.watch(productKey);
        String value = jedis.get(productKey);
        int num = Integer.valueOf(value);
        //這次秒殺的商品是100個iphone8
        if (num <= 100 && num >= 1) {
            //開啓事務
            Transaction tx = jedis.multi();
            //減少一個商品數量
            tx.incrBy(productKey, -1);
            //提交事務,如果商品數量發生了改動 則會返回null
            List<Object> list = tx.exec();
            if (list == null || list.size() == 0) {
                System.out.println(userName + "商品搶購失敗!");
            } else {
                for (Object success : list) {
                    System.out.println(userName + "(" + success.toString() + ")商品搶購成功,當前搶購成功的人數是:" + (1 - (num - 100)));
                }
            }
        } else {
            System.out.println(userName + "商品已經被搶完了");
        }
        jedis.close();
    }


    /**
     * 測試連接redis庫
     * @param args
     */
    public static void main(String[] args) {
        // 連接本地的 Redis 服務
        Jedis jedis = new Jedis("192.168.17.128");
        System.out.println("連接本地的 Redis 服務成功!");
        // 查看服務是否運行
        System.out.println("服務 正在運行: " + jedis.ping());
    }


}

測試啓動類如下

package redis;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import redis.clients.jedis.Jedis;

public class TestMs {

    public static void main(String[] args) throws InterruptedException {
        Jedis jedis = new Jedis("192.168.17.128");
        jedis.set("iphone8","100");
        jedis.close();
        //玩多線程
        ExecutorService executor = Executors.newFixedThreadPool(15);

        for(int i = 0 ; i < 1000; i++){
            executor.execute(new SaleRunable("user" + i));
        }
        executor.shutdown();
        System.out.println("搶購完成!");

    }
}

開啓20個線程運行結果如下:

redis查看數據,還剩 27個。。

多次模擬,數據在賣出80個左右浮動,開啓線程數越大,賣出的越少。。。

開啓15個及小於15個線程,結果如下,基本上能賣完,多次運行偶爾會有1-2次賣出99個
redis數據庫數據
啥情況呢?

源代碼地址:
https://www.cnblogs.com/longtaosoft/p/6627568.html
https://blog.csdn.net/lzh657083979/article/details/77917088

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章