本代码是基于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