packagecom.vian.user.service;importorg.junit.Test;importorg.springframework.util.CollectionUtils;importredis.clients.jedis.Jedis;importredis.clients.jedis.JedisPool;importredis.clients.jedis.JedisPoolConfig;importredis.clients.jedis.Transaction;importjava.io.IOException;importjava.util.List;importjava.util.concurrent.CountDownLatch;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;/**秒杀测试*/
public classSecondKillTest {
@Testpublic voidgetResult() {
Jedis jedis=JedisPoolUtil.getJedis();
String goodsResult= jedis.get("goodsResult:user102");
System.out.println(goodsResult);
}
@Testpublic void test() throwsIOException, InterruptedException {/**初始化商品*/initGoods();/**1000线程抢购100个商品*/ExecutorService executorService= Executors.newFixedThreadPool(20);
CountDownLatch count= new CountDownLatch(10000);long startTime =System.currentTimeMillis();for (int i = 0; i < 10000; i++) {
executorService.execute(new SecondKillHandlder("user" +i));
count.countDown();
}
executorService.shutdown();
count.await();long time = System.currentTimeMillis() -startTime;
System.out.println("共耗时:" + time + "毫秒");//JedisPoolUtil.close();
System.in.read();
}/**初始化商品数量*/
private voidinitGoods() {
Jedis jedis=JedisPoolUtil.getJedis();
jedis.set("goods:iphone8", "100"); //设置100个商品
JedisPoolUtil.returnRes(jedis);
}/**秒杀处理线程*/
private static class SecondKillHandlder implementsRunnable {
String goodsKey= "goods:iphone8"; //监视的key 当前秒杀商品的数量
Jedis jedis;
String userName;publicSecondKillHandlder(String userName) {this.userName =userName;
}
@Overridepublic voidrun() {while (true) {try{
jedis=JedisPoolUtil.getJedis();//watch 监视一个key,当事务执行之前这个key发生了改变,事务会被打断
jedis.watch(goodsKey);int currentGoodsCount = Integer.parseInt(jedis.get(goodsKey)); //当前剩余商品数量
if (currentGoodsCount <= 0) {
System.out.println("商品已抢完," + userName + "---> 抢购失败 XXX");break;
}
Transaction tran= jedis.multi(); //开启事务
tran.incrBy(goodsKey, -1); //商品数量-1
List exec = tran.exec(); //执行事务
if(CollectionUtils.isEmpty(exec)) {
System.out.println(userName+ "---> 抢购失败,继续抢购");
Thread.sleep(1);
}else{
exec.forEach(
succ->{
String succStr=userName+ "===========================> 抢购到第【"
+ ((100 - currentGoodsCount) + 1)+ "】份商品,该商品剩余:"
+succ.toString();
System.out.println(succStr);
jedis.set("goodsResult:" + userName, succStr); //业务代码,处理抢购成功
});break;
}
}catch(Exception e) {
e.printStackTrace();
}finally{if (jedis != null) {
jedis.unwatch();
JedisPoolUtil.returnRes(jedis);
}
}
}
}
}private static classJedisPoolUtil {private staticJedisPool pool;private static voidcreateJedisPool() {//建立连接池配置参数
JedisPoolConfig config = newJedisPoolConfig();//设置最大连接数
config.setMaxTotal(100);//设置最大阻塞时间,记住是毫秒数milliseconds
config.setMaxWaitMillis(1000);//设置空间连接
config.setMaxIdle(10);//创建连接池
pool = new JedisPool(config, "192.168.31.201", 6379, 2000, null, 3);
}/**在多线程环境同步初始化*/
private static synchronized voidpoolInit() {if (pool == null) createJedisPool();
}/*** 获取一个jedis 对象
*
*@return
*/
public staticJedis getJedis() {if (pool == null) poolInit();returnpool.getResource();
}/*** 归还一个连接
*
*@paramjedis*/
public static voidreturnRes(Jedis jedis) {
pool.returnResource(jedis);
}public static voidclose() {
pool.close();
}
}
}