好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Java实现抢红包功能

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

关键思想:

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

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

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

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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

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定时将红包信息推送给玩家。每一批玩家的抢红包请求,其实操作的都是从队列中弹出的第一个红包元素,但当前的红包数量为空的时候,自动弹出下一个红包(如果有的话)。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

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

  }

  }

}

运行结果部分截图如下

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

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

原文链接:https://blog.csdn.net/littleschemer/article/details/46382117

查看更多关于Java实现抢红包功能的详细内容...

  阅读:67次