采用多线程模拟多人同时抢红包。服务端将玩家发出的红包保存在一个队列里,然后用Job定时将红包信息推送给玩家。每一批玩家的抢红包请求,其实操作的都是从队列中弹出的第一个红包元素,但当前的红包数量为空的时候,自动弹出下一个红包(如果有的话)。

关键思想:

1.抢红包涉及多人并发操作,需要做好同步保证多线程运行结果正确。

2.由于同时在线人数大,从性能方面考虑,玩家的发红包请求不必及时响应,而由服务端定时执行发红包队列。

下面是主要的代码和实现逻辑说明

1.创建一个类,表示红包这个实体概念。直接采用原子变量保证增减同步。Java的原子变量是一种精度更细的同步机制,在高度竞争的情况下,锁的性能将超过原子变量的性能,但在更真实的竞争情况,原子变量享有更好的性能。

public class SpringGift {

private String role;

private AtomicInteger gift;

public String getRole() {

return role;

}

public void setRole(String role) {

this.role = role;

}

public AtomicInteger getGift() {

return gift;

}

public void setGift(AtomicInteger gift) {

this.gift = gift;

}

public int getRemainCount(){

return this.gift.get();

}

}

2.采用多线程模拟多人同时抢红包。服务端将玩家发出的红包保存在一个队列里,然后用Job定时将红包信息推送给玩家。每一批玩家的抢红包请求,其实操作的都是从队列中弹出的第一个红包元素,但当前的红包数量为空的时候,自动弹出下一个红包(如果有的话)。

public class Test {

public static ConcurrentLinkedQueue queue;

public static SpringGift currGift;

public static AtomicInteger count = new AtomicInteger();

static class myThread implements Runnable{

public void run(){

handleEvent();

}

}

public static void main(String[] args) throws Exception {

queue = new ConcurrentLinkedQueue();

for(int i =0;i<3;i++){

SpringGift gift = new SpringGift();

gift.setRole("role"+i);

gift.setGift(new AtomicInteger(50));

queue.add(gift);

}

myThread mythread = new myThread();

for(int i=0;i<1000;i++){

new Thread(mythread).start();

}

System.err.println("总共收到"+count.get());

}

private static SpringGift getGift(){

//防止多条线程同时弹出队首

synchronized (queue) {//若没有加锁,打印的count总数不对!!!!

if(currGift == null || currGift.getRemainCount() <=0){

currGift = queue.poll();

}

}

return currGift;

}

public static void handleEvent(){

try{

SpringGift obj = getGift();

if(obj == null || obj.getRemainCount() <= 0){

System.err.println("没有了");

return ;

}

if(obj !=null && obj.getGift().getAndDecrement() >0 ){

System.err.println("抢到一个红包");

count.getAndIncrement();

}

Thread.sleep(500);//模拟处理其他操作

}catch(Exception e){

e.printStackTrace();

}

}

}

运行结果部分截图如下

需要注意的是,getGift()这个方法,由于是自动弹出队首元素,必须做好同步机制,否则,当多个请求同时操作某一个红包的最后一次剩余时,会造成总的红包数量不正确。

(将加锁的代码注释后,会发现打印的总数量有可能不正确了!)

java基础多线程抢红包_Java实现抢红包功能相关推荐

  1. java基础-多线程应用案例展示

    java基础-多线程应用案例展示 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.两只熊,100只蜜蜂,蜜蜂每次生产的蜂蜜量是1,罐子的容量是30,熊在罐子的蜂蜜量达到20的时候 ...

  2. java基础多线程抢红包_高并发开发-微信抢红包实现

    - 如果上司给一个任务,让我们在实现微信抢红包这个功能,我们该怎么做? * 业务思考,实现方式千百种,不追求方法复制,只追求推导过程的思考总结 * 功能点探索 * 新建红包:在DB.cache各新增一 ...

  3. java 基础知识巩固_Java基础巩固——《Java核心技术基础·卷一:基础知识》

    阅读记录追踪:前言部分 阅读前先看:简介.目录和勘误! Java编程语言是一种多用途.并发的.基于类的.面向对象的编程语言:编译时通常包括将持续转化成机器无关的字节码表示.运行时活动包括加载和链接执行 ...

  4. java的多线程机制_Java多线程开发(一)| 基本的线程机制

    0. 前言 Java 为了实现跨平台,在语言层面上实现了多线程.我们只需要熟悉 Java 这一套多线程机制就行了,比 C/C++ 要容易多了. 1. 定义任务 我们编写程序,最终是为了完成特定的任务. ...

  5. 2020 - [Java基础 +多线程 + 虚拟机] + [计网 + 操作系统] + [MySQL] + [Redis] + [RocketMQ] + [Spring]常见面试题与解析

    前情提要:下面的内容主要由网上的资料和个人的理解整理而成.由于时间仓促可能没有给出相应的链接,并不代表我不尊重他人的劳动成果,后续更新会补上相应的链接.其中内容可能有理解不到位的地方,大家可选择性采纳 ...

  6. java基础知识面试_Java 基础面试知识点

    Java 基础知识相关 Java中 == 和 equals 和 hashCode 的区别 对于关系操作符 == 若操作数的类型是基本数据类型,则该关系操作符判断的是左右两边操作数的值是否相等 若操作数 ...

  7. java基础之 反射_Java基础之反射原理与用法详解

    本文实例讲述了Java基础之反射原理与用法.分享给大家供大家参考,具体如下: 1.什么是反射? 反射其实就是动态的加载类,我们在写JDBC的时候加载驱动Class.forName("xxx& ...

  8. java并发多线程面试_Java多线程并发面试问答

    java并发多线程面试 Today we will go through Java Multithreading Interview Questions and Answers. We will al ...

  9. java基础自学教程_Java基础自学教程(全套)

    Java基础自学教程(全套)视频简介: Java是计算机领域中一种非常重要的程序设计语言,也是一款优秀的纯面向对象语言.第一视频教程分享的这部Java基础自学教程是一部非常不错的教程.它详细讲述了JA ...

  10. java基础小项目_java基础小项目练习之1----3天做出飞机大战

    Shoot射击游戏第一天 一.关键问题(理论): 1.简述FlyingObject.Enemy.Award.Airplane.Bee.Bullet.Hero之间的继承与实现关系 2.简述Hero类构造 ...

最新文章

  1. 关于ie,火狐,谷歌浏览器滚动条的隐藏以及自定义样式
  2. 我爱我家:我为什么选择AppCan?
  3. turtle python tkinter_【案例】 什么?idle 中竟然有内置 turtle 样例?(paint)
  4. emui10如何降级_如何评价EMUI10按包名降分辨率机制的行为?
  5. 数学--数论--莫比乌斯反演
  6. TTL and CMOS 的几个基本功能模块
  7. linux 分隔大文件,linux系统下分割大文件的方法
  8. 增加或修改的存储过程
  9. 期待已久的Java 9 今日正式发布,新特性解读
  10. Perl脚本常用操作
  11. 什么是http服务器
  12. 大学四年的总结与感受
  13. jQuery基础入门
  14. 数字中国城市巡礼之开封:千年古都的智慧新生
  15. 最新YGbook小说网自适应源码 自动采集笔趣阁 附详细图文安装教程
  16. QGIS学习资料及地理数据下载
  17. bat 批处理 B站缓存视频转成 .mp4格式
  18. 带你白嫖程序带宽限制命令Trickle
  19. Qt 程序异常结束 并且crashed——解决方法 (动态链接库)
  20. 加工过程中,如何选择正确的铣刀以及加工方式?

热门文章

  1. postfix 邮箱搭建
  2. git revert讲解
  3. 谈一谈git revert和revert the revert
  4. tensor.contiguous()
  5. PHP验证歌德巴赫猜想:一个充分大的偶数(大于或等于6)可以分解为两个素数之和。编写程序,将6至50之间全部偶数表示为两个素数之和。
  6. 拓展欧几里得小结(转载)
  7. 神经网络梯度消失的解释
  8. i9 13900K参数 i9 13900K核显相当于什么显卡
  9. 沉浸式看球,VR让看球更有参与感
  10. Towards Noise Resilient SLAM