java发红包redis_求知识,java redis抢红包问题

以下是模拟300人同时抢200个红包的实例,但是实际测试中,最后保存已拿红包的都是少于200人,是什么原因?是redis丢数据了还是其他的?

public Map autoGetRedPackage() throws Exception {

Map returnMap = new HashMap();

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 end = redisService.getListQueue(key);

if (end == null || end.size() <= 0) {

break;

}

}

logger.info(redisService.getListQueueSize(key));

logger.info(redisService.getListQueueSize(finshKey));

List listFinish = redisService.getListQueue(finshKey);

List returnRedPackageList = new ArrayList();

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;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值