java多线程抢红包_Java线程操作-模拟本地多线程抢红包

这是一个Java模拟多线程抢红包的程序,通过线程锁保证并发安全性。程序中,当红包总数不为0时,多个线程可尝试抢红包,每次抢到后减少库存,最终统计每个线程抢到的红包数量并验证总库存是否正确。
摘要由CSDN通过智能技术生成

没有写过抢红包的处理程序,考虑到多线程是核心,所以练习先写一个本地使用多线程来抢红包的模拟程序。程序运行要达到的效果,是最终红包都被抢完,并对数据进行统计,统计结果和总库存要完全吻合。

没有过多的解释,直接就一个测试类。

package com.chris.java;

import java.util.HashMap;

import java.util.Map;

/**

* Created by Chris Chan

* 2020/2/11 19:27

* Use for:

* Explain: 线程测试

*/

public class TestThread {

private static volatile int amount = 1143;//红包总数

private static Mapmap = new HashMap<>(16);//记录每个线程抢到的红包

private static Object boxLock = new Object();//线程锁 可以假设是装红包的盒子

public static void main(String[] args) {

action();

}

//抢红包

private static void action() {

Runnable runnable = () -> {

String threadName = Thread.currentThread().getName();

while (amount > 0) {

//抢一次 独占这把锁 加锁部分的操作应该越少越好,减少时间消耗,可以提升性能

synchronized (boxLock) {

/*

可以想象,在最后的一个红包被抢前,有一大堆人(线程)在后面排队获取这把锁,

如果让这些已经进入循环的线程继续,则后面这些线程可能会继续抢一些

不存在的红包,使红包库存编程负数。所以需要在这里检查一下盒子里面

是否空空如也。

*/

if (amount <= 0) {

break;

}

amount--;//减库存 如果不想打印控制台信息,就用这一行替换下面一行

//减库存放在这一行中,是为了避免两次控制台输出造成过多的时间消耗

//System.out.println("红包库存 " + (amount--) + "个 线程 " + threadName + " 抢到一个红包 还剩 " + amount + " 个");

//下面这一行代码只是为了便于检查,其实不必要,会增加时间消耗

// if (amount % 5 == 0) {

// System.out.println();

// }

}

Integer total = map.get(threadName);

if (null == total) {

map.put(threadName, 1);

} else {

map.put(threadName, total + 1);

}

}

};

Thread thread01 = new Thread(runnable);

Thread thread02 = new Thread(runnable);

Thread thread03 = new Thread(runnable);

thread01.start();

thread02.start();

thread03.start();

try {

Thread.sleep(5000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("\n汇总:\n红包还剩 " + amount + " 个");

map.keySet().stream().forEach(key -> System.out.println("\t" + key + " : " + map.get(key)));

System.out.println("红包一共被领取 " + map.values().stream().reduce(0, (v1, v2) -> v1 + v2) + " 个");

}

}

开始时遇到一些问题,就是变-1,后来添加来加锁后检查的逻辑才解决。一般这种问题都是解决问题的思路需要调整,生活中如何解决问题,程序中就如何实现逻辑。解决了前者,后者也就不是什么问题。另外加锁后的操作应该尽可能少消耗时间,否则可能造成时间片消费的不均衡。

运行结果:

b2b90912dc47919c53bb5e59fc0038f7.png

换过几次参数都没有什么问题,不过这只是本地测试,逻辑要简单很多。下次写一个全套的前后端测试程序,需要用好http请求,红包数据要放在数据库。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值