<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency>
将jedis注入到spring中,略
@Autowired JedisPool jedisPool;
public static void main(String[] args) {
//连接本地的 Redis 服务
Jedis inputJedis = new Jedis("localhost", 6379);
String RDIS_FILE_KEY = "Rdis_File_key";
for (int i = 0; i < 10; i++) {
inputJedis.lpush(RDIS_FILE_KEY,"aaaa"+10);
}
//=====================抢购代码==================
//表示进行100次抢,但是程序线程在20个.进去了20个其他排队在等20人出来再进去
ExecutorService executorService = Executors.newFixedThreadPool(20);
CountDownLatch countDown = new CountDownLatch(100);
for (int i = 0; i <100; i++) {
int index = i;
executorService.execute(() -> {
Jedis checkJedis = new Jedis("localhost", 6379);
Long zcard = checkJedis.llen(RDIS_FILE_KEY);
System.err.println(Thread.currentThread().getName()+"======"+zcard);
if (zcard>0){
String result = checkJedis.lpop(RDIS_FILE_KEY);
System.out.println("用户"+index+" 抱歉已抢走!"+result);
countDown.countDown();
return;
}
//表示一个线程执行完毕了
countDown.countDown();
System.err.println(Thread.currentThread().getName()+"没有任何商品,结束战斗");
checkJedis.close();
});
}
executorService.shutdown();
try {
//等待所有线程执行完毕
countDown.await();
System.out.println("所有用户秒杀完毕,开始公布结果:");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
下面是源码,在servie层函数中接口执行 :
生产数据
String goodsKey = "goods:iphone8";
Jedis jedis = jedisPool.getResource();
jedis.set(goodsKey, "100"); // 设置100个商品
jedisPool.returnResource(jedis);
开始抢购:
/** 1000线程抢购100个商品 */
ExecutorService executorService = Executors.newFixedThreadPool(20);
CountDownLatch count = new CountDownLatch(10000);
long startTime = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
int finalI = i;
executorService.execute(new Runnable() {
@Override
public void run() {
Jedis jedis =null;
while (true) {
try {
jedis = jedisPool.getResource();
// watch 监视一个key,当事务执行之前这个key发生了改变,事务会被打断
jedis.watch(goodsKey);
int currentGoodsCount = Integer.parseInt(jedis.get(goodsKey)); // 当前剩余商品数量
if (currentGoodsCount <= 0) {
System.out.println("商品已抢完," + finalI + "---> 抢购失败 XXX");
break;
}
Transaction tran = jedis.multi(); // 开启事务
tran.incrBy(goodsKey, -1); // 商品数量-1
List<Object> exec = tran.exec(); // 执行事务
if (CollectionUtil.isEmpty(exec)) {
System.out.println(finalI + "---> 抢购失败,继续抢购");
Thread.sleep(1);
} else {
Jedis finalJedis = jedis;
exec.forEach(
succ -> {
String succStr = finalI + "===========================> 抢购到第【"
+ ((100 - currentGoodsCount) + 1)
+ "】份商品,该商品剩余:"
+ succ.toString();
System.out.println(succStr);
finalJedis.set("goodsResult:" + finalI, succStr); // 业务代码,处理抢购成功
});
break;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (jedis != null) {
jedis.unwatch();
jedisPool.returnResource(jedis);
}
}
}
}
});
count.countDown();
}
executorService.shutdown();
try {
count.await();
long time = System.currentTimeMillis() - startTime;
System.out.println("共耗时:" + time + "毫秒");
// JedisPoolUtil.close();
System.in.read();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}