[Java学习日记]多线程练习、线程池

目录

一.案例:五个人抢红包

二.案例:两个抽奖池抽奖

三.案例:两个抽奖池抽奖:获取线程运行的结果

四.线程池:用来存放线程,避免多次重复创建线程

五.自定义线程池

六.最大并行数与线程池大小


一.案例:五个人抢红包

1.如何保证只留下两位小数,并且计算精确呢?
使用大浮点数类,使用setScale方法保留小数
2.如何保证随机的数字最小是一分钱呢?
设置最小中奖金额,如果随机到的数字小于这个数的话,就让这个数变成这个最小金额
同时也需要保证最大的金额不会大到把剩下人的一分钱(最小金额)也给吞掉了
3.如果说是最后一个抽到红包的,还应该去随机数字吗
直接把剩余的钱款给最后一个即可在这里的随机金额中先抢的概率更大-这或许也是不合理的地方
public class Demo321 {public static void main(String[] args) {MyThread t1 = new MyThread();MyThread t2 = new MyThread();MyThread t3 = new MyThread();MyThread t4 = new MyThread();MyThread t0 = new MyThread();t1.start();t2.start();t3.start();t4.start();t0.start();}
}
public class MyThread extends Thread {static BigDecimal money = BigDecimal.valueOf(100);static int count = 3;static final BigDecimal MIN = BigDecimal.valueOf(0.01);@Overridepublic void run() {synchronized (MyThread.class) {if (count == 0) {System.out.println(Thread.currentThread().getName() + "来晚一步!");return;}BigDecimal price;if (count == 1) price = money;elseprice = BigDecimal.valueOf(new Random().nextDouble(MIN.doubleValue(),money.subtract(BigDecimal.valueOf(count-1).multiply(MIN)).doubleValue()));count--;price = price.setScale(2, RoundingMode.HALF_UP);money = money.subtract(price);System.out.println(Thread.currentThread().getName() + "抢到了" + price + "元");}}
}

 


二.案例:两个抽奖池抽奖

public class Demo322 {public static void main(String[] args) {MyThread t1 = new MyThread();MyThread t0 = new MyThread();t1.start();t0.start();System.out.println("到这一行就开启了三条线程");System.out.println("main方法是运行在main线程中的栈,线程12开启的时候在内存中会多出两个栈:线程一的方法栈和线程2的方法栈");}
}
public class MyThread extends Thread {static ArrayList<Integer> arrayList;static {arrayList = new ArrayList<>();Collections.addAll(arrayList, 10, 5, 20, 50, 100, 200, 500, 800, 2, 80, 300, 700);}@Overridepublic void run() {ArrayList<Integer> myArraylist = new ArrayList<>();while (true) {synchronized (MyThread.class) {if (arrayList.size() == 0) break;int index = new Random().nextInt(arrayList.size());Integer i = arrayList.get(index);arrayList.remove(index);myArraylist.add(i);}}synchronized (Thread.class) {if (myArraylist.size() == 0) {System.out.println("在此抽奖过程中,"+getName() + "没有产生任何奖项");return;}System.out.println("在此抽奖过程中," + getName() + "共产生了" + myArraylist.size() + "个奖项" + "分别为");StringJoiner sj = new StringJoiner(",");Integer count = 0;Integer max = myArraylist.get(0);for (Integer integer : myArraylist) {sj.add(integer + "");count += integer;if (integer > max) max = integer;}System.out.println(sj + "," + "最高奖项为" + max + "元," + "总计额为" + count + "元");}}
}


三.案例:两个抽奖池抽奖:获取线程运行的结果

public class Demo323 {public static void main(String[] args) throws ExecutionException, InterruptedException {MyCallable myCallable = new MyCallable();System.out.println("需要注意的点:这里要创建两个多线程运行结果的管理对象");FutureTask<Integer> futureTask0 = new FutureTask<>(myCallable);FutureTask<Integer> futureTask1= new FutureTask<>(myCallable);Thread t0 = new Thread(futureTask0);Thread t1 = new Thread(futureTask1);t0.start();t1.start();Integer i0 = futureTask0.get();Integer i1 = futureTask1.get();System.out.println("在这个抽奖过程中");if (i1==null||i0>i1){System.out.print(t0.getName()+"抽到了最大奖项,该奖金金额为:"+i0+"元");}else {System.out.print(t1.getName()+"抽到了最大奖项,该奖金金额为:"+i1+"元");}}
}
class MyCallable implements Callable<Integer> {static ArrayList<Integer> arrayList;static {arrayList = new ArrayList<>();Collections.addAll(arrayList, 10, 5, 20, 50, 100, 200, 500, 800, 2, 80, 300, 700);}@Overridepublic Integer call(){ArrayList<Integer> myArraylist = new ArrayList<>();while (true) {synchronized (MyThread.class) {if (arrayList.size() == 0) break;int index = new Random().nextInt(arrayList.size());Integer i = arrayList.get(index);arrayList.remove(index);myArraylist.add(i);}}synchronized (Thread.class) {if (myArraylist.size() == 0) {System.out.println("在此抽奖过程中,"+Thread.currentThread().getName() + "没有产生任何奖项");return null;}System.out.println("在此抽奖过程中," + Thread.currentThread().getName()  + "共产生了" + myArraylist.size() + "个奖项" + "分别为");StringJoiner sj = new StringJoiner(",");Integer count = 0;Integer max = myArraylist.get(0);for (Integer integer : myArraylist) {sj.add(integer + "");count += integer;if (integer > max) max = integer;}System.out.println(sj + "," + "最高奖项为" + max + "元," + "总计额为" + count + "元");return max;}}
}


四.线程池:用来存放线程,避免多次重复创建线程

提交任务时,线程池会创建新的线程对象,任务执行完毕之后,线程归还给池子
1.下次再创建任务的时候还需要创建新的线程吗?
不需要再创建新的线程,复用已经有的线程即可
2.如果提交任务的时候池子里面没有空闲线程,就无法创建新的线程,任务会如何进行?
任务就会排队等待3.线程池创建过程?
1.创建线程池
2.提交任务
3.所有任务执行完毕时,关闭线程池(实际开发中线程池一般不会关闭)4.创建线程池的快速方法?
使用Executors(执行人)的静态方法创建线程池5.如何创建无上限的线程池?
6.如何提交任务?
7.如何停止线程?
8.如何创建有上限的线程池?
public class Demo324 {public static void main(String[] args) throws InterruptedException {System.out.println("5.使用Executors的newCachedThread方法获取线程池对象(cached-缓存),无上限");ExecutorService pool = Executors.newCachedThreadPool();System.out.println("6.使用线程池的submit方法提交任务,这里的输出的线程池名字与线程名字编号都是从1开始的");pool.submit(new MyRunnable());pool.submit(new MyRunnable());Thread.sleep(1000);//在这里睡了一小会之后使用的还是原来的线程:不会创建新的线程(用线程一还是线程二是随机的)pool.submit(new MyRunnable());Thread.sleep(1000);System.out.println("7.使用线程池的shutdown方法停止线程");pool.shutdown();Thread.sleep(1000);System.out.println("8.使用Executors的newFixedThreadPool方法创建有上限的线程池");pool = Executors.newFixedThreadPool(1);pool.submit(new MyRunnable());pool.submit(new MyRunnable());pool.shutdown();}
}
public class MyRunnable implements Runnable{@Overridepublic void run() {for (int i = 0; i < 10; i++) {System.out.println(Thread.currentThread().getName()+":"+i);}}
}

 


五.自定义线程池

自定义线程池 参数如下:
1.核心线程数量(核心员工)
2.线程中最大线程数量(包括临时员工)
3.4.临时线程空闲时间与单位(临时员工存活时间)
5.阻塞队列
6.创建线程的方式
7.要执行任务过多的解决方案创建临时线程的时机是在什么时候?
阻塞队列满了之后才能创建,不是核心线程被占满了才创建,创建临时线程处理队伍之外的任务!
public class Demo325 {public static void main(String[] args) {ThreadPoolExecutor tpe = new ThreadPoolExecutor(3,6,60,TimeUnit.SECONDS,//时间单位new ArrayBlockingQueue<>(3),//不想指定长度就写LinkedArrayBlockingQueueExecutors.defaultThreadFactory(),//创建线程工厂,底层是创建Thread线程new ThreadPoolExecutor.AbortPolicy()//静态内部类(依赖于线程池,单独存在无意义),任务的默认拒绝策略:抛错);tpe.submit(new MyRunnable());tpe.submit(new MyRunnable());tpe.submit(new MyRunnable());tpe.submit(new MyRunnable());tpe.submit(new MyRunnable());tpe.submit(new MyRunnable());tpe.submit(new MyRunnable());tpe.submit(new MyRunnable());tpe.submit(new MyRunnable());tpe.shutdown();}
}

在上面代码基础上再加一个线程会报错: 


六.最大并行数与线程池大小

最大并行数:和CPU有关
Intel利用-超线程技术-使得每个核有两个线程
在设备管理器可以查看
1.如何获取最大能够使用的线程?2.线程池开多大合适呢?
项目一般分为:CPU密集型(计算比较多)和IO密集型(读写文件多)
CPU密集型:
PU运算比较多,最大并行数+1(1是备用池)即可
IO密集型(大多数项目):
最大并行数(8)*期望CPU利用率(占满100%)*[(计算时间+等待时间(等待IO流))/计算时间]这个需要用工具(thread dump)计算
public class Demo326 {public static void main(String[] args) {System.out.println("2.使用Runtime.getRuntime().availableProcessors()获取当前最多能够使用的线程");System.out.println(Runtime.getRuntime().availableProcessors());}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/197799.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【EI会议征稿】第九届电气、电子和计算机工程研究国际学术研讨会 (ISAEECE 2024)

第九届电气、电子和计算机工程研究国际学术研讨会 (ISAEECE 2024) 2024 9th International Symposium on Advances in Electrical, Electronics and Computer Engineering 第九届电气、电子和计算机工程研究国际学术研讨会(ISAEECE 2024&#xff09;将于2024年3月1-5日在南京…

AWS攻略——创建VPC

文章目录 创建一个可以外网访问的VPCCIDR主路由表DestinationTarget 主网络ACL入站规则出站规则 子网创建EC2测试连接创建互联网网关&#xff08;IGW&#xff09;编辑路由表 知识点参考资料 在 《AWS攻略——VPC初识》一文中&#xff0c;我们在AWS默认的VPC下部署了一台可以SS…

鸿蒙4.0开发笔记之ArkTS装饰器语法基础之监听者模式@Watch案例讲解(十四)

1、Watch定义 Watch实际是指状态变量更改通知。如果开发者需要关注某个状态变量的值是否改变&#xff0c;可以使用Watch为状态变量设置回调函数&#xff08;监听函数&#xff09;。 Watch用于监听状态变量的变化&#xff0c;当状态变量变化时&#xff0c;Watch的回调方法将被…

隐写术和人工智能

在一项新的研究中&#xff0c;人工智能对齐研究实验室 Redwood Research 揭示了大型语言模型 (LLM) 可以掌握“编码推理”&#xff0c;这是一种隐写术形式。 这种有趣的现象使得大型语言模型能够以人类读者无法理解的方式巧妙地将中间推理步骤嵌入到生成的文本中。 大型语言…

C++初阶 | [七] string类(上)

摘要&#xff1a;标准库中的string类的常用函数 C语言中&#xff0c;字符串是以\0结尾的一些字符的集合&#xff0c;为了操作方便&#xff0c;C标准库中提供了一些str系列的库函数&#xff0c; 但是这些库函数与字符串是分离开的&#xff0c;不太符合OOP(面向对象)的思想&#…

03、pytest初体验

官方实例 # content of test_sample.py def func(x):return x 1def test_ansewer():assert func(3) 5步骤解释 [100%]指的是所有测试用例的总体进度&#xff0c;完成后&#xff0c;pytest显示一个失败报告&#xff0c;因为func(3)没有返回5 注意&#xff1a;你可以使用ass…

【滤波第二期】中值滤波的原理和C代码

中值滤波是一种非线性数字滤波技术&#xff0c;主要应用于信号处理和图像处理领域&#xff0c;用于减小信号中的噪声和离群值。中值滤波的核心思想是通过计算一组数据点的中间值&#xff0c;以抑制脉冲噪声等离群值的影响&#xff0c;从而实现信号的平滑处理。 1&#xff0c;中…

<Linux>(极简关键、省时省力)《Linux操作系统原理分析之linux存储管理(5)》(21)

《Linux操作系统原理分析之linux存储管理&#xff08;5&#xff09;》&#xff08;21&#xff09; 6 Linux存储管理6.6 Linux 物理空间管理6.6.1 Linux 物理内存空间6.6.2 物理页面的管理6.6.3 空闲页面管理——buddy 算法 6.7 内存的分配与释放6.7.1 物理内存分配的数据结构 6…

canvas绘制小丑

说明&#xff1a; 借鉴博主基于canvas绘制一个爱心(10行代码就够了) - 掘金 (juejin.cn) 代码实现 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content&quo…

实现简单的Http服务器+SpringMvc,集成到Spring

实现简单的Http服务器SpringMvc&#xff0c;集成到Spring 1、Http协议 1.1、HTTP 协议请求格式 方法 空格 URL 空格 版本 回车符 换行符头部域名称&#xff1a;头部域值 回车符 换行符...头部域名称&#xff1a;头部域值 回车符 …

【UGUI】sprite精灵的创建与编辑

如何切图&#xff08;sprite editor&#xff09; 有时候一张图可能包含了很多张子图&#xff0c;就需要在Unity 临时处理一下&#xff0c;切开&#xff0c;比如动画序列帧图集 虽然我们可以在PS里面逐个切成一样的尺寸导出多张&#xff0c;再放回Unity&#xff0c;但是不需要这…

音视频技术开发周刊 | 322

每周一期&#xff0c;纵览音视频技术领域的干货。 新闻投稿&#xff1a;contributelivevideostack.com。 超级AI不会主宰人类&#xff0c;但人工智能必须开源&#xff01;LeCun最新采访引全网300万人围观 LeCun最新访谈视频中&#xff0c;再次坦露了自己对开源AI的看法。超级AI…

安路Anlogic FPGA下载器的驱动安装教程

安路FPGA下载器驱动安装教程 安路FPGA下载器&#xff1a;EN-ALC10,是一款高性能FPGA下载线&#xff08;编程器&#xff09;&#xff0c;支持安路的开发软件TDS和全系列FPGA芯片下载编程&#xff0c;支持全速USB2.0与电脑进行数据通信&#xff0c;通过JTAG协议与FPGA进行程序下…

vue自定义指令:指定文字高亮

vue自定义指令&#xff1a;指定文字高亮 自定义指令 除了核心功能默认内置的指令 (v-model 和 v-show)&#xff0c;Vue 也允许注册自定义指令。注意&#xff0c;在 Vue2.0 中&#xff0c;代码复用和抽象的主要形式是组件。然而&#xff0c;有的情况下&#xff0c;你仍然需要对…

JS实现成才网注册系统(网页数据验证)

主代码 <!DOCTYPE htmlPUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"http://www.w3.org/1999/xhtml"><head><meta http-equiv"Conten…

Hadoop进阶学习---HDFS分布式文件存储系统

1.hdfs分布式文件存储的特点 分布式存储:一次写入,多次读取 HDFS文件系统可存储超大文件,时效性较差. HDFS基友硬件故障检测和自动快速恢复功能. HDFS为数据存储提供很强的扩展能力. HDFS存储一般为一次写入,多次读取,只支持追加写入,不支持随机修改. HDFS可以在普通廉价的机器…

llama.cpp部署(windows)

一、下载源码和模型 下载源码和模型 # 下载源码 git clone https://github.com/ggerganov/llama.cpp.git# 下载llama-7b模型 git clone https://www.modelscope.cn/skyline2006/llama-7b.git查看cmake版本&#xff1a; D:\pyworkspace\llama_cpp\llama.cpp\build>cmake --…

Leetcode1038. 从二叉搜索树到更大和树(每日一题)

目录 ⚽题目&#xff1a; &#x1f3d0;题目分析&#xff1a; &#x1f3c0;题目解答&#xff1a; &#x1f94e;代码如下&#xff1a; ⚽题目&#xff1a; 给定一个二叉搜索树 root (BST)&#xff0c;请将它的每个节点的值替换成树中大于或者等于该节点值的所有节点值…

SSM项目实战-前端-在Index.vue中展示第一页数据

1、util/request.js import axios from "axios";let request axios.create({baseURL: "http://localhost:8080",timeout: 50000 });export default request 2、api/schedule.js import request from "../util/request.js";export let getSchedu…

传输层可靠传输的原理

目录 1.停止等待协议 2.连续ARQ协议 3.TCP报文段的首部格式 4.TCP的滑动窗口机制 &#xff08;1&#xff09;发送窗口 &#xff08;2&#xff09;接收窗口 &#xff08;3&#xff09;发送缓存 5.超时重传时间的选择 6.选择确认SACK(Selective ACK) 7.使用滑动窗口实现…