多线程学习之多线程的案例
练习一:赠送礼物
需求:有100份礼品,两人同时发送,当剩下的礼品小于10份的时候则不再送出。利用多线程模拟该过程并将线程的名字和礼物的剩余数量打印出来.
示例:
public class MyRunable implements Runnable {//第二种方式实现多线程,测试类中MyRunable只创建一次,所以不需要加staticint count = 100;@Overridepublic void run() {//1.循环while (true) {//2.同步代码块synchronized (MyThread.class) {//3.判断共享数据(已经到末尾)if (count < 10) {System.out.println("礼物还剩下" + count + "不再赠送");break;} else {//4.判断共享数据(没有到末尾)count--;System.out.println(Thread.currentThread().getName() + "在赠送礼物,还剩下" + count + "个礼物!!!");}}}}
}public class Test {public static void main(String[] args) {/*有100份礼品,两人同时发送,当剩下的礼品小于10份的时候则不再送出,利用多线程模拟该过程并将线程的名字和礼物的剩余数量打印出来.*///创建参数对象MyRunable mr = new MyRunable();//创建线程对象Thread t1 = new Thread(mr,"窗口1");Thread t2 = new Thread(mr,"窗口2");//启动线程t1.start();t2.start();}
}
练习二:打印数字
需求:同时开启两个线程,共同获取1-100之间的所有数字。共同输出所有的奇数。
实例:
public class MyRunable implements Runnable {//第二种方式实现多线程,测试类中MyRunable只创建一次,所以不需要加staticint number = 1;@Overridepublic void run() {//1.循环while (true) {//2.同步代码块synchronized (MyThread.class) {//3.判断共享数据(已经到末尾)if (number > 100) {break;} else {//4.判断共享数据(没有到末尾)if(number % 2 == 1){System.out.println(Thread.currentThread().getName() + "打印数字" + number);}number++;}}}}
}public class Test {public static void main(String[] args) {//创建参数对象MyRunable mr = new MyRunable();//创建线程对象Thread t1 = new Thread(mr,"线程A");Thread t2 = new Thread(mr,"线程B");//启动线程t1.start();t2.start();}
}
练习三:抢红包
需求:
抢红包也用到了多线程。
假设:100块,分成了3个包,现在有5个人去抢。
其中,红包是共享数据。
5个人是5条线程。
打印结果如下:
XXX抢到了XXX元
XXX抢到了XXX元
方案一:
public class MyThread extends Thread{public static double money = 100.0;public static int count = 3;//最小的中奖金额public static final double MIN = 0.01;@Overridepublic void run(){//同步代码块synchronized (MyThread.class){if(count == 0){//红包抢完了System.out.println(Thread.currentThread().getName() + "没有抢到红包");}else{//红包还有//定义一个当前金额的变量double price = 0;if(count == 1){//只有一个红包了 则无需随机直接赋值即可price = money;}else {//是第一个和第二个红包 进行随机Random random = new Random();//100 元 3个包//第一个红包:100 - (3-1) * 0.01 = 99.98 设置的是边界,这样random就会在这个范围内选取int bounds = money - (count-1) * MIN;price = random.nextInt(bounds);if(price < MIN){price = MIN;}}//从money当中,去掉当前中奖的金额money = money - price;//红包的个数-1count--;//本次红包的信息进行打印System.out.println(getName() + "抢到了" + price + "元");}}}
}public class Test {public static void main(String[] args) {//创建线程的对象MyThread t1 = new MyThread();MyThread t2 = new MyThread();MyThread t3 = new MyThread();MyThread t4 = new MyThread();MyThread t5 = new MyThread();//给线程设置名字t1.setName("kk");t2.setName("oneone");t3.setName("11");t4.setName("kunkun");t5.setName("ii");//启动线程t1.start();t2.start();t3.start();t4.start();t5.start();}
}
方案二:
//总金额static BigDecimal money = BigDecimal.valueOf(100.0);//个数static int count = 3;//最小抽奖金额static final BigDecimal MIN = BigDecimal.valueOf(0.01);@Overridepublic void run() {synchronized (MyThread.class){if(count == 0){System.out.println(getName() + "没有抢到红包!");}else{//中奖金额BigDecimal prize;if(count == 1){prize = money;}else{//获取抽奖范围double bounds = money.subtract(BigDecimal.valueOf(count-1).multiply(MIN)).doubleValue();Random r = new Random();//抽奖金额prize = BigDecimal.valueOf(r.nextDouble(bounds));}//设置抽中红包,小数点保留两位,四舍五入prize = prize.setScale(2,RoundingMode.HALF_UP);//在总金额中去掉对应的钱money = money.subtract(prize);//红包少了一个count--;//输出红包信息System.out.println(getName() + "抽中了" + prize + "元");}}}
练习四:抽奖箱
需求:
有一个抽奖池,该抽奖池中存放了奖励的金额,该抽奖池中的奖项为 {10,5,20,50,100,200,500,800,2,80,300,700};
创建两个抽奖箱(线程)设置线程名称分别为“抽奖箱1”,“抽奖箱2”
随机从抽奖池中获取奖项元素并打印在控制台上,格式如下:
每次抽出一个奖项就打印一个(随机)
抽奖箱1 又产生了一个 10 元大奖
实例:
public class MyThread extends Thread {ArrayList<Integer> list;public MyThread(ArrayList<Integer> list) {this.list = list;}@Overridepublic void run() {//1.循环//2.同步代码块//3.判断//4.判断while (true) {synchronized (MyThread.class) {if (list.size() == 0) {break;} else {//继续抽奖Collections.shuffle(list);int prize = list.remove(0);System.out.println(getName() + "又产生了一个" + prize + "元大奖");}}try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}}
}public class Test {public static void main(String[] args) {/*有一个抽奖池,该抽奖池中存放了奖励的金额,该抽奖池中的奖项为 {10,5,20,50,100,200,500,800,2,80,300,700};创建两个抽奖箱(线程)设置线程名称分别为“抽奖箱1”,“抽奖箱2”随机从抽奖池中获取奖项元素并打印在控制台上,格式如下:每次抽出一个奖项就打印一个(随机)抽奖箱1 又产生了一个 10 元大奖抽奖箱1 又产生了一个 100 元大奖抽奖箱1 又产生了一个 200 元大奖抽奖箱1 又产生了一个 800 元大奖抽奖箱2 又产生了一个 700 元大奖.....*///创建奖池ArrayList<Integer> list = new ArrayList<>();Collections.addAll(list,10,5,20,50,100,200,500,800,2,80,300,700);//创建线程MyThread t1 = new MyThread(list);MyThread t2 = new MyThread(list);//设置名字t1.setName("抽奖箱1");t2.setName("抽奖箱2");//启动线程t1.start();t2.start();}
}
练习五:多线程统计并求最大值
需求:
在上一题基础上继续完成如下需求:
每次抽的过程中,不打印,抽完时一次性打印(随机)
在此次抽奖过程中,抽奖箱1总共产生了6个奖项。
分别为:10,20,100,500,2,300最高奖项为300元,总计额为932元
在此次抽奖过程中,抽奖箱2总共产生了6个奖项。
分别为:5,50,200,800,80,700最高奖项为800元,总计额为1835元
方案一:
public class MyThread extends Thread {ArrayList<Integer> list;public MyThread(ArrayList<Integer> list) {this.list = list;}//线程一static ArrayList<Integer> list1 = new ArrayList<>();//线程二static ArrayList<Integer> list2 = new ArrayList<>();@Overridepublic void run() {while (true) {synchronized (MyThread.class) {if (list.size() == 0) {if("抽奖箱1".equals(getName())){System.out.println("抽奖箱1" + list1);}else {System.out.println("抽奖箱2" + list2);}break;} else {//继续抽奖Collections.shuffle(list);int prize = list.remove(0);if("抽奖箱1".equals(getName())){list1.add(prize);}else {list2.add(prize);}}}try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}}
}public class Test {public static void main(String[] args) {/*有一个抽奖池,该抽奖池中存放了奖励的金额,该抽奖池中的奖项为 {10,5,20,50,100,200,500,800,2,80,300,700};创建两个抽奖箱(线程)设置线程名称分别为“抽奖箱1”,“抽奖箱2”随机从抽奖池中获取奖项元素并打印在控制台上,格式如下:每次抽的过程中,不打印,抽完时一次性打印(随机) 在此次抽奖过程中,抽奖箱1总共产生了6个奖项。分别为:10,20,100,500,2,300最高奖项为300元,总计额为932元在此次抽奖过程中,抽奖箱2总共产生了6个奖项。分别为:5,50,200,800,80,700最高奖项为800元,总计额为1835元*///创建奖池ArrayList<Integer> list = new ArrayList<>();Collections.addAll(list,10,5,20,50,100,200,500,800,2,80,300,700);//创建线程MyThread t1 = new MyThread(list);MyThread t2 = new MyThread(list);//设置名字t1.setName("抽奖箱1");t2.setName("抽奖箱2");//启动线程t1.start();t2.start();}
}
方案二:
public class MyThread extends Thread {ArrayList<Integer> list;public MyThread(ArrayList<Integer> list) {this.list = list;}@Overridepublic void run() {ArrayList<Integer> boxList = new ArrayList<>();//1 //2while (true) {synchronized (MyThread.class) {if (list.size() == 0) {System.out.println(getName() + boxList);break;} else {//继续抽奖Collections.shuffle(list);int prize = list.remove(0);boxList.add(prize);}}try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}}
}public class Test {public static void main(String[] args) {/*有一个抽奖池,该抽奖池中存放了奖励的金额,该抽奖池中的奖项为 {10,5,20,50,100,200,500,800,2,80,300,700};创建两个抽奖箱(线程)设置线程名称分别为“抽奖箱1”,“抽奖箱2”随机从抽奖池中获取奖项元素并打印在控制台上,格式如下:每次抽的过程中,不打印,抽完时一次性打印(随机) 在此次抽奖过程中,抽奖箱1总共产生了6个奖项。分别为:10,20,100,500,2,300最高奖项为300元,总计额为932元在此次抽奖过程中,抽奖箱2总共产生了6个奖项。分别为:5,50,200,800,80,700最高奖项为800元,总计额为1835元*///创建奖池ArrayList<Integer> list = new ArrayList<>();Collections.addAll(list,10,5,20,50,100,200,500,800,2,80,300,700);//创建线程MyThread t1 = new MyThread(list);MyThread t2 = new MyThread(list);//设置名字t1.setName("抽奖箱1");t2.setName("抽奖箱2");//启动线程t1.start();t2.start();}
}
练习六:
需求:
在上一题基础上继续完成如下需求:
在此次抽奖过程中,抽奖箱1总共产生了6个奖项,分别为:10,20,100,500,2,300
最高奖项为300元,总计额为932元
在此次抽奖过程中,抽奖箱2总共产生了6个奖项,分别为:5,50,200,800,80,700
最高奖项为800元,总计额为1835元
在此次抽奖过程中,抽奖箱2中产生了最大奖项,该奖项金额为800元
以上打印效果只是数据模拟,实际代码运行的效果会有差异
public class MyCallable implements Callable<Integer> {ArrayList<Integer> list;public MyCallable(ArrayList<Integer> list) {this.list = list;}@Overridepublic Integer call() throws Exception {ArrayList<Integer> boxList = new ArrayList<>();//1 //2while (true) {synchronized (MyCallable.class) {if (list.size() == 0) {System.out.println(Thread.currentThread().getName() + boxList);break;} else {//继续抽奖Collections.shuffle(list);int prize = list.remove(0);boxList.add(prize);}}Thread.sleep(10);}//把集合中的最大值返回if(boxList.size() == 0){return null;}else{return Collections.max(boxList);}}
}package com.itheima.test7;import java.util.ArrayList;
import java.util.Collections;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;public class Test {public static void main(String[] args) throws ExecutionException, InterruptedException {/*有一个抽奖池,该抽奖池中存放了奖励的金额,该抽奖池中的奖项为 {10,5,20,50,100,200,500,800,2,80,300,700};创建两个抽奖箱(线程)设置线程名称分别为 "抽奖箱1", "抽奖箱2"随机从抽奖池中获取奖项元素并打印在控制台上,格式如下:在此次抽奖过程中,抽奖箱1总共产生了6个奖项,分别为:10,20,100,500,2,300最高奖项为300元,总计额为932元在此次抽奖过程中,抽奖箱2总共产生了6个奖项,分别为:5,50,200,800,80,700最高奖项为800元,总计额为1835元在此次抽奖过程中,抽奖箱2中产生了最大奖项,该奖项金额为800元核心逻辑:获取线程抽奖的最大值(看成是线程运行的结果)以上打印效果只是数据模拟,实际代码运行的效果会有差异*///创建奖池ArrayList<Integer> list = new ArrayList<>();Collections.addAll(list,10,5,20,50,100,200,500,800,2,80,300,700);//创建多线程要运行的参数对象MyCallable mc = new MyCallable(list);//创建多线程运行结果的管理者对象//线程一FutureTask<Integer> ft1 = new FutureTask<>(mc);//线程二FutureTask<Integer> ft2 = new FutureTask<>(mc);//创建线程对象Thread t1 = new Thread(ft1);Thread t2 = new Thread(ft2);//设置名字t1.setName("抽奖箱1");t2.setName("抽奖箱2");//开启线程t1.start();t2.start();Integer max1 = ft1.get();Integer max2 = ft2.get();System.out.println(max1);System.out.println(max2);//在此次抽奖过程中,抽奖箱2中产生了最大奖项,该奖项金额为800元if(max1 == null){System.out.println("在此次抽奖过程中,抽奖箱2中产生了最大奖项,该奖项金额为"+max2+"元");}else if(max2 == null){System.out.println("在此次抽奖过程中,抽奖箱1中产生了最大奖项,该奖项金额为"+max1+"元");}else if(max1 > max2){System.out.println("在此次抽奖过程中,抽奖箱1中产生了最大奖项,该奖项金额为"+max1+"元");}else if(max1 < max2){System.out.println("在此次抽奖过程中,抽奖箱2中产生了最大奖项,该奖项金额为"+max2+"元");}else{System.out.println("两者的最大奖项是一样的");}}
}
相关文章:
多线程学习之多线程的案例
练习一:赠送礼物 需求:有100份礼品,两人同时发送,当剩下的礼品小于10份的时候则不再送出。利用多线程模拟该过程并将线程的名字和礼物的剩余数量打印出来. 示例: public class MyRunable implements Runnable {//第二种方式实现…...
iTOP-RK3588开发板Android12 设置系统默认不休眠
修改文件: device/rockchip/rk3588/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults. xml 文件,如下图所示: - <integer name"def_screen_off_timeout">60000</integer> <integer name&q…...
java系统问题定位思路
一、在不同环境排查问题,有不同的方式 1、如果是在自己的开发环境排查问题,那你几乎可以使用任何自己熟悉的工具来排查,甚至可以进行单步调试。只要问题能重现,排查就不会太困难,最多就是把程序调试到 JDK 或三方类库内…...
redis jedis 单元测试 报错集锦 汇总 junit
redis报错汇总 在单元测试时,使用jedis通常遇到如下报错: 实例化报错->连接报错->权限报错。此报错是有顺序的:例如,若连接报错,说明实例化完成,即配置文件配对了。若权限报错,说明连接…...
AMEYA360:兆易创新获得ISO 26262 ASIL D流程认证, 汽车功能安全管理体系再上新台阶
中国北京(2023年8月29日) —— 业界半导体器件供应商兆易创新GigaDevice(股票代码 603986)今日宣布,获得由国际公认的测试、检验和认证机构通标标准技术服务有限公司(以下简称SGS)授予的ISO 26262:2018汽车功能安全最高等级ASIL D流程认证证书,这标志着兆…...
MySQL binlog的几种日志录入格式以及区别
🏆作者简介,黑夜开发者,CSDN领军人物,全栈领域优质创作者✌,CSDN博客专家,阿里云社区专家博主,2023年6月CSDN上海赛道top4。 🏆数年电商行业从业经验,历任核心研发工程师…...
C# 案例题
1. // # hello world using System; namespace HelloWorldApplication {class HelloWorld{static void Main(string[] args) {/*my first C# program*/Console.WriteLine("HelloWorld C#");Console.ReadKey();}} } 2. // C# 计算矩形的面积 /*计…...
拒绝摆烂!C语言练习打卡第七天
🔥博客主页:小王又困了 📚系列专栏:每日一练 🌟人之为学,不日近则日退 ❤️感谢大家点赞👍收藏⭐评论✍️ 目录 一、选择题 📝1.第一题 📝2.第二题 Ὅ…...
【动态规划】状态压缩dp
【动态规划】状态压缩dp...
Java eight 解读流(Stream)、文件(File)、IO和异常处理的使用方法
目录 Java 流(Stream)、文件(File)和IO读取控制台输入读写文件FileInputStreamFileOutputStream Java目录 Java 异常处理 Java 流(Stream)、文件(File)和IO java.io 包几乎包含了所有操作输入、输出需要的类。所有这些流类代表了输入源和输出目标。 Java.io 包中的流支持很多种…...
胜券汇:行业持续轮动 缺乏主线下关注反转预期的方向
前史行情4年一轮回,中心在于微观环境的类似性。首要,复盘前史,2016-2019年和2020年至今的行情走势较为类似,历经约1年半的长牛,约1年的长熊,阅历1个季度快速反弹后继续约3个季度的震动期。其次,…...
java+ssm+mysql农场信息管理系统
项目介绍: 本系统为基于jspssmmysql的农场信息管理系统,功能如下: 用户:注册登录系统,菜地信息管理,农作物信息管理,种植信息管理,客户信息管理,商家信息管理ÿ…...
【App出海成功案例】 | NetMarvel 帮助广告主ARPU增长45%,ECPM增长50%,付费率涨幅30%
中国App何以扬帆出海? 出海热发展到今天,中国App席卷西方世界的神话被一一打造,手游/非游双面开花,成功案例作为赛道代表,也成为众多出海广告主一一效仿的风向标。 它们在用户增长、变现收益上的打法是怎样的&#x…...
CSDN每日一练 |『鬼画符门莲台争夺战』『等差数列』『 路灯亮度』2023-08-31
CSDN每日一练 |『鬼画符门莲台争夺战』『等差数列』『 路灯亮度』2023-08-31 一、题目名称:鬼画符门莲台争夺战二、题目名称:等差数列三、题目名称:等差数列四、题目名称:路灯亮度路灯亮度』2023-08-31) 一、题目名称:鬼画符门莲台争夺战 时间限制:1000ms内存限制:256M …...
自编码器AE全方位探析:构建、训练、推理与多平台部署
本文深入探讨了自编码器(AE)的核心概念、类型、应用场景及实战演示。通过理论分析和实践结合,我们详细解释了自动编码器的工作原理和数学基础,并通过具体代码示例展示了从模型构建、训练到多平台推理部署的全过程。 关注TechLead&…...
SpringBoot - Google EventBus、AsyncEventBus
介绍 EventBus 顾名思义,事件总线,是一个轻量级的发布/订阅模式的应用模式,最初设计及应用源与 google guava 库。 相比于各种 MQ 中间件更加简洁、轻量,它可以在单体非分布式的小型应用模块内部使用(即同一个JVM范围…...
Tauri打包windows应用配置中文界面
使用 Tauri Rust 开发桌面应用,在 windows 系统上,打包后安装包名称后缀、安装界面、相关说明默认都是英文的。如果要默认显示为中文,则需要在 tauri.conf.json 中配置相应参数。 前言 默认情况下,在 windows 系统打完的 mis 包…...
深度丨Serverless + AIGC,一场围绕加速创新的升维布局
作者:褚杏娟 上图来源于基于函数计算部署 SD实现光影效果 前言: Serverless 在中国发展这些年,经历了高潮、低谷、现在重新回到大众视野。很多企业都非常感兴趣,部分企业开始大规模应用;也有一些企业对在生产环境真正…...
flask日志
您可以使用 Python 自带的 logging 模块来实现 Flask 日志记录功能。以下是一个简单的示例: import os import logging from logging.handlers import TimedRotatingFileHandler from flask import Flask, requestapp Flask(__name__)# 创建日志目录 if not os.pa…...
新能源汽车动力总成系统及技术
需要动力系统总成的请联:shbinzer 拆车邦 需要动力系统总成的请联:shbinzer 拆车邦 需要动力系统总成的请联:shbinzer 拆车邦 需要动力系统总成的请联:shbinzer 拆车邦 需要动力系统总成的请联:shbinzer …...
Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
