当前位置: 首页 > news >正文

【多线程】 线程池设多大才合理?CPU 密集型和 I/O 密集型的终极公式

 在开始之前,让我们高喊我们的口号:

键盘敲烂,年薪百万!

我听说关注我的人未来都会暴富哦!


目录

键盘敲烂,年薪百万!

我听说关注我的人未来都会暴富哦!

引言

线程池

自定义线程池 

代码实现 

线程池多大合适?

什么是最大并行数?

怎么看电脑的最大并行数?


引言

一个故事,你有一个碗,吃完饭,摔了。下一顿,你得去买个碗,然后又吃饭,吃完又摔了。下一顿……

这很不方便,每次吃饭都要去买碗。于是解决方法就是买个碗柜,把碗放起来。

学到这里,你会发现,你需要线程就创建一个,而且一个线程完了就结束了。这样会极大的浪费操作系统的资源。所以我们准备一个容器存放线程,这个容器被称为线程池。

线程池

线程池核心(普通情况):给线程池提交一个任务的时候,线程池就创建一个线程去执行这个任务,执行完了就把线程还回线程池。下次再提交一个任务的时候,不需要再创建一个线程,而是用已经存在的线程去执行任务,再还回去。

特殊情况:

当提交第二个任务给线程池的时候,前一个线程正在执行第一个线程,那么这个时候线程池就会再创建一个线程去执行第二个任务,再还回线程池。以此类推,当345个任务要现成执行但是其他两个线程还在执行任务的时候,线程池会再创建345个线程来执行345任务,再还回线程池。

注意线程池是有上限的而且可以自己指定,这里如果指定线程池中只能创建3个线程,那45个任务只能等有空闲的线程后才可以执行。

 这里的没有上限其实是假的,有上限,上限是整数的最大值,也就是21亿多个线程。但是呢,你的电脑创建不了那么多个线程就爆了。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class MyThreadPoolDemo {public static void main(String[] args) throws InterruptedException {/*public static ExecutorService newCachedThreadPool()             创建一个没有上限的线程池public static ExecutorService newFixedThreadPool (int nThreads) 创建有上限的线程池*///1.获取线程池对象ExecutorService pool1 = Executors.newFixedThreadPool(3);//2.提交任务pool1.submit(new MyRunnable());pool1.submit(new MyRunnable());pool1.submit(new MyRunnable());pool1.submit(new MyRunnable());pool1.submit(new MyRunnable());pool1.submit(new MyRunnable());//3.销毁线程池//pool1.shutdown();}
}
public class MyRunnable implements Runnable{@Overridepublic void run() {for (int i = 1; i <= 100; i++) {System.out.println(Thread.currentThread().getName() + "---" + i);}}
}

自定义线程池 

为什么要自定义?因为用java已经写好的明显并不够灵活。所以要学会自定义线程池。

一个故事理解:

一个饭店,有3名正式员工,3名临时员工。且这个饭店最大只能有6个员工。那么当人少的时候,3个正式员工和3个临时员工就可以了。但是当只有3个人来的时候,临时员工隔固定的时间段还没服务人就被辞退。当人大于6个人,饭店规定10个人之后就不要排队啦,明儿个再来!

具体解释:

过程:任务123分别创建123个核心线程去执行,规定了队伍长度为3,所以后面456任务在后面排队,任务78就被临时创建的线程45执行。什么时候创建临时线程?所以当任务数大于核心线程数和队伍长度且小于核心线程,队伍长度,临时线程数总和时,会创建临时线程。

但是当任务数超过总和时候,也就是核心线程在执行,排队排满了,而临时线程也在执行。这个时候就会引发 任务拒绝策略。

如果用第三种方式则会把线程4丢弃并把线城10拿进去排队。因为线程4最先排队,排队时间最长。

代码实现 

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;public class MyThreadPoolDemo1 {public static void main(String[] args){/*ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(核心线程数量,最大线程数量,空闲线程最大存活时间,任务队列,创建线程工厂,任务的拒绝策略);参数一:核心线程数量              不能小于0参数二:最大线程数                不能小于0,最大数量 >= 核心线程数量参数三:空闲线程最大存活时间       不能小于0参数四:时间单位                  用TimeUnit指定参数五:任务队列                  不能为null参数六:创建线程工厂              不能为null参数七:任务的拒绝策略             不能为null*/ThreadPoolExecutor pool = new ThreadPoolExecutor(3,  //核心线程数量,能小于06,  //最大线程数,不能小于0,最大数量 >= 核心线程数量60,//空闲线程最大存活时间TimeUnit.SECONDS,//时间单位new ArrayBlockingQueue<>(3),//任务队列Executors.defaultThreadFactory(),//创建线程工厂new ThreadPoolExecutor.AbortPolicy()//任务的拒绝策略);}
}

线程池多大合适?

 

什么是最大并行数?

 以8核16线程为例

相当于有8个大脑,只能同时并行做8件事情。但是windows发明了超线程技术,让8个大脑影分身为16,可以同时并行做16件事情。这个同时并行可以做的最大数就是最大并行数。

怎么看电脑的最大并行数?

1.在此电脑点击右键,然后点击属性,在属性里找到设备管理器,再打开处理器,里面如果有16个那么最大并行数是16

2.有的电脑会隐藏起来一些,不告诉你最大并行数具体是多少。用idea执行下面的代码可以查看到真实的最大并行数。

public class MyThreadPoolDemo2 {public static void main(String[] args) {//向Java虚拟机返回可用处理器的数目int count = Runtime.getRuntime().availableProcessors();System.out.println(count);}
}

 多大合适?

cpu密集型:计算多而读取少

I/O密集型运算:读取多而计算少,现在主流

cpu计算时间和等待时间怎么办呢?

可以用tread dump这个工具来测试。 


今天的分享就到这里,欢迎在评论区交流

一起学习,一起进步!

如果你能关注我

那就是对我创作的最大鼓励啦!

http://www.lryc.cn/news/587232.html

相关文章:

  • 深度学习图像分类数据集—七种树叶识别分类
  • AI生成单词消消乐游戏. HTML代码
  • LeetCode 2401.最长优雅子数组
  • Ampace厦门新能安科技Verify 测评演绎数字推理及四色测评考点分析、SHL真题题库
  • 【sql学习之拉链表】
  • 系规备考论文:论IT服务知识管理
  • MyBatis框架进阶指南:深入理解CRUD与参数映射
  • CVE-2022-0609
  • Oracle SQL - 使用行转列PIVOT减少表重复扫描(实例)
  • 常用的docker命令备份
  • Docker从环境配置到应用上云的极简路径
  • 《Google 软件工程》:如何写好文档?
  • Qt窗口:QToolBar、QStatusBar、QDockWidget、QDialog
  • QT 多线程 管理串口
  • Vue框架之计算属性与侦听器详解
  • 深入理解 LangChain:AI 应用开发的全新范式
  • openEuler欧拉系统重置密码
  • 标注识别 自己的数据集20张 roboflow 实例分割
  • 基于requests_html的爬虫实战
  • 【DVWA系列】——File Upload——low详细教程(webshell工具冰蝎)
  • Vue Router 完全指南:从入门到实战,高效管理前端路由
  • 12.I/O复用
  • 光盘处理难题不用愁,DVDFab 来救场
  • 博客项目 laravel vue mysql 第五章 标签功能
  • 从 Intel MacBook 迁移到 ARM MacBook 的完整指南
  • 【牛客刷题】四个选项:高考选择题方案统计(并查集+动态规划)
  • 【基于开源大模型(如deepseek)开发应用及其发展趋势的一点思考】
  • 时序预测 | Matlab代码实现VMD-TCN-GRU-MATT变分模态分解时间卷积门控循环单元多头注意力多变量时序预测
  • 【Linux系统】进程状态 | 进程优先级
  • 未来航空电子系统