81,094
社区成员
发帖
与我相关
我的任务
分享
public Map<String, Object> autoGetRedPackage() throws Exception {
Map<String, Object> returnMap = new HashMap<String, Object>();
long companyId = 45243043L;
int max = 100;
int min = 2;
int total = 10000;
int count = 200;
//将大红包拆分成小红包数组
long[] rpDatas = RedPacketAlgorithm.generate(total, count, max, min);
logger.info("红包生成数:" + rpDatas.length);
// 将生成的红包放入队列中
final String key = "red_packet_auto_" + UUID.randomUUID().toString();
for (int i = 1; i <= rpDatas.length; i++) {
Msg msg = new Msg();
msg.setId(i);
msg.setMoney(rpDatas[i-1]);
msg.setSourceUserId(companyId);
try {
redisService.leftPush(key, msg);
} catch (Exception e) {
logger.error(e.getMessage(), e);
return returnMap;
}
}
// 已经领取用户列表
final String mapKey = "hasGet_" + key;
// 最后生成的领取记录队列
final String finshKey = "finish_" + key;
/**
* 接收到一个获取红包请求 判断是否已经领取过 如果没有,则从redis队列中取出一个分给该用户 添加该用户的领取记录 如果没有,则返回已经领取完 将完成队列处理入库
*/
//模拟300人同时不同的抢红包
int threadNum = 300;
for (int i = 1; i <= threadNum; i++) {
final String temp = Integer.toString(i);
Thread thread = new Thread() {
public void run() {
try {
String lockKey = key + "_" + temp;
while (true) {
//加锁60秒
Object isForbidRedObject = redisService.getByValue(lockKey);
boolean isForbidRed = false;
if (isForbidRedObject != null) {
isForbidRed = (boolean) isForbidRedObject;
}
if (!isForbidRed) {
//60秒内只能点一次,防止并发多抢
redisService.insertByValue(lockKey, true, 60, TimeUnit.SECONDS);
//查看是否已领取队列
Object isGetRedObject = redisService.getByHash(mapKey, temp);
boolean isGetRed = false;
if (isGetRedObject != null) {
isGetRed = (boolean) isGetRedObject;
}
if (!isGetRed) {
try {
logger.info("size:" + redisService.getListQueueSize(key));
//弹出红包
Object data = redisService.rightPop(key);
if (data != null) {
LinkedHashMap map = (LinkedHashMap) data;
Msg msg = new Msg();
msg.setId((int) map.get("id"));
msg.setMoney((int) map.get("money"));
msg.setGetUserId(Long.parseLong(temp));
msg.setSourceUserId((int) map.get("sourceUserId"));
//插入到完成队列
redisService.leftPush(finshKey, msg);
//插入到已领取hast
redisService.insertByHash(mapKey, temp, true);
logger.info("恭喜[" + temp + "]用户," + "领红包成功,money:"
+ msg.getMoney());
break;
} else {
Long redPackageLength = redisService
.getListQueueSize(key);
if (redPackageLength == null || redPackageLength <= 0) {
logger.info("尊敬的[" + temp + "]用户," + "红包已经领取完了");
break;
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
} else {
logger.info("尊敬的[" + temp + "]用户,您已经领取过了,做人要厚道");
break;
}
}
Long redPackageLength = redisService.getListQueueSize(key);
if (redPackageLength == null || redPackageLength <= 0) {
logger.info("尊敬的[" + temp + "]用户," + "红包已经领取完了");
break;
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
} finally {
}
}
};
thread.start();
}
while (true) {
List<LinkedHashMap> end = redisService.getListQueue(key);
if (end == null || end.size() <= 0) {
break;
}
}
logger.info(redisService.getListQueueSize(key));
logger.info(redisService.getListQueueSize(finshKey));
List<LinkedHashMap> listFinish = redisService.getListQueue(finshKey);
List<Msg> returnRedPackageList = new ArrayList<Msg>();
for (LinkedHashMap map : listFinish) {
Msg msg = new Msg();
msg.setId((int) map.get("id"));
msg.setMoney((int) map.get("money"));
msg.setGetUserId((int) map.get("getUserId"));
msg.setSourceUserId((int) map.get("sourceUserId"));
returnRedPackageList.add(msg);
}
returnMap.put("result", returnRedPackageList);
return returnMap;
}