Java实现抢红包功能

作者:littleschemer 时间:2021-08-05 07:47:58 

本文实例为大家分享了Java实现抢红包功能的具体代码,供大家参考,具体内容如下

关键思想:

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<SpringGift> 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<SpringGift>();
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();
}
}
}

运行结果部分截图如下

Java实现抢红包功能

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

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

来源:https://blog.csdn.net/littleschemer/article/details/46382117

标签:java,抢红包
0
投稿

猜你喜欢

  • Kafka常用命令之kafka-console-consumer.sh解读

    2022-06-11 00:20:32
  • java 文件上传到读取文件内容的实例

    2023-11-09 22:00:27
  • Java中后台线程实例解析

    2022-01-05 06:45:08
  • SpringBoot集成MyBatis的分页插件PageHelper实例代码

    2023-09-11 21:54:33
  • SpringBoot项目中使用Mockito的示例代码

    2023-09-25 22:31:14
  • SpringBoot整合Zookeeper详细教程

    2022-07-24 11:33:09
  • 如何查找YUM安装的JAVA_HOME环境变量详解

    2023-04-01 11:48:22
  • Spring中的@Transactional的工作原理

    2023-08-06 02:00:04
  • Springboot实现Shiro整合JWT的示例代码

    2022-01-30 02:58:32
  • 关于java中构造函数的一些知识详解

    2023-11-27 22:09:11
  • 详解java接口(interface)在不同JDK版本中的变化

    2022-07-18 03:19:16
  • C#编程自学之数据类型和变量一

    2023-07-30 02:45:49
  • spring mvc 组合mybatis框架实例详解

    2023-11-28 04:56:04
  • Java虚拟机内存结构及编码实战分享

    2023-11-29 13:47:47
  • 十分钟速懂java知识点 System类

    2022-11-25 04:19:26
  • Java实现身份证号码验证源码示例分享

    2022-12-24 03:58:50
  • IDEA教程创建SpringBoot前后端分离项目示例图解

    2022-06-30 02:41:10
  • Java发送邮件遇到的常见需求汇总

    2021-10-07 14:51:02
  • 深入了解Hadoop如何实现序列化

    2023-10-13 10:33:43
  • HashMap原理及put方法与get方法的调用过程

    2023-10-06 03:53:02
  • asp之家 软件编程 m.aspxhome.com