private static AtomicLong salesCount = new AtomicLong(100000);
private final String updateStockHold = "local key = KEYS[1] \n"
+ "local count = ARGV[1] \n"
+ "redis.call('decrby', key, count) \n"
+ "local afterCount = redis.call('get', key) \n"
+ "if (tonumber(afterCount) < 0) then \n"
+ " redis.call('incrby', key, count) \n"
+ " return afterCount \n"
+ "else \n"
+ " return afterCount \n"
+ "end \n";
@Test
public void testRedisService() throws InterruptedException, BrokenBarrierException {
Jedis jedis = setupSentinelPool();
jedis.set("iphone_count", "100000");
final CyclicBarrier cyclicBarrier =new CyclicBarrier(21);
ExecutorService executorService = Executors.newFixedThreadPool(20);
int times = 20;
while (times > 0) {
Thread.sleep(10);
executorService.submit(new Runnable() {
@Override
public void run() {
Jedis jedis = setupSentinelPool();
int runTimes = 3000;
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
while (runTimes > 0) {
int count = 1;
String luaAcquireLockSHA = jedis.scriptLoad(updateStockHold);
Object obj = jedis.evalsha(luaAcquireLockSHA, 1, "iphone_count", String.valueOf(count));
System.out.println("After Update Count:" + obj);
// System.out.println("After Update Count : " + jedis.get("iphone_count"));
runTimes--;
if (Long.parseLong(obj.toString()) >= 0) {
salesCount.addAndGet(-1);
}else {
break;
}
if(Thread.currentThread().isInterrupted()){
break;
}
}
}
});
times--;
}
cyclicBarrier.await();
System.out.println("Start Time Unit " + new Date());
executorService.awaitTermination(1, TimeUnit.SECONDS);
executorService.shutdownNow();
System.out.println("End Time Unit " + new Date());
Thread.sleep(100);
System.out.println("Final Result : " + jedis.get("iphone_count"));
System.out.println("Final Result Expected: " + salesCount.get());
}
private Jedis setupSentinelPool() {
try {
// 1.配置Apache-Commons连接池属性
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
poolConfig.setMaxTotal(1);
poolConfig.setMaxIdle(1);
poolConfig.setMinIdle(1);
poolConfig.setBlockWhenExhausted(true);
poolConfig.setMaxWaitMillis(500);
poolConfig.setLifo(false);
poolConfig.setTestOnBorrow(false);
poolConfig.setTestOnReturn(false);
poolConfig.setTestWhileIdle(true);
poolConfig.setTimeBetweenEvictionRunsMillis(30000);
poolConfig.setNumTestsPerEvictionRun(-1);
poolConfig.setMinEvictableIdleTimeMillis(60);
// 2.获取Sentinel地址
String[] addrs = redisCacheConfig.getSentinels().split(";");
Set<String> sentinelSet = new HashSet<String>();
for (String addr : addrs) {
sentinelSet.add("172.19.9.230:6601");
}
JedisSentinelPool pool = new JedisSentinelPool("mkt-cache", sentinelSet, poolConfig,
2000, "redis1");
logger.info("[CACHE]JedisSentinelPool init completed.");
return pool.getResource();
} catch (Throwable e) {
// logger.error("[CACHE]init fail", e);
throw new InitializationException("RedisClient init fail", e);
} finally {
}
}