java多线程编程(四)-----线程池

一.线程池的介绍

java中的池是非常重要的思想方法,比如内存池,进程池,连接池,常量池等等。本篇重点介绍java中的线程池。这里的这些池的概念都是一样的,比如做饭的时候,有烧水,切菜,炒菜等流程,如果等水烧开再去炒菜,切菜效率会很慢,但是可以烧水的同时去切菜,炒菜,效率大幅提升。如果我们需要频繁的创造和销毁线程,此时创建和销毁线程的成本就不能忽视了,因此可以使用线程池。提前创建好一波线程,后续需要用线程只需要从线程池中拿,线程用完后继续放到池子里面。思考一下为什么从池子里面取,就比从系统中创建线程更快更高效呢?
在这里插入图片描述
假如小明要去银行取钱,这个时候发现忘记复印身份证了,小明现在有2个选择,1是把身份证交给柜台服务人员由他们去复印,但服务人员手里同时要处理很多事情,等身份证复印完可能已经花费了很多时间,是不可控的行为。但是如果自己在大厅复印机上复印,复印的时间完全自己掌握,同时属于可控行为,效率大幅度提升。线程也是这样,如果从系统中创建线程,需要调用系统api,进一步由操作系统内核完成(内核相当于柜台),内核是给所有进程提供服务的,通常也需要处理很多事情,是不可控的。如果从线程池这里获取线程,上述内核中要做的操作,现在在获取线程的过程中,纯粹由用户代码完成。

二.java标准库的线程池

java标准库中也提供了现成的线程池
1.创建一个固定线程数的线程池
在这里插入图片描述
2.创建一个线程数目动态变化的线程池
在这里插入图片描述
3.创建单个线程的线程池
在这里插入图片描述
4.创建定时器效果的线程池
在这里插入图片描述

一.工产方法

在这里插入图片描述
看到这种写法是不是语法很难看懂,并没有new一个对象就直接调用方法。其实这种写法是java设计模式中的工产模式,一般创建对象都是通过new,通过构造方法。但是通过构造方法有重大缺陷,构造方法名字固定就是类名,有的类需要多种不同的方法构造,但是构造方法的名字又固定,就只能使用重载的方式来实现了,但是参数的个数和类型有差别。
在这里插入图片描述
一个坐标可以由横坐标和纵坐标组成,也可以由半径和角度描述,但是如果2个构造方法的参数和类型相同会报错,这也就是构造方法的一个缺陷,为了解决这个问题引入了工产模式。使用普通方法来构造对象,这样方法的名字就可以是任意的了,普通方法内部再来new对象,由于普通方法目的是为了创建出对象来,这样的方法一般是静态的。
在这里插入图片描述
接着看一个工产模式的实例:

interface Shape{void run(int a,int b,String str);
}
class Range implements Shape{public int x;public  int y;@Overridepublic void run(int x,int y,String str) {System.out.println("横纵坐标相加等于"+(x+y));}
}
class  Tangle implements  Shape{@Overridepublic void run(int r,int a,String str) {System.out.println("半径乘以角度等于"+r*a);}
}
class Point1{public static Shape PointXY(int x,int y,String str){if(str=="Range"){Range range = new Range();range.run(x,y,str);return range;}else if(str=="Tange"){Tangle tangle = new Tangle();tangle.run(x,y,str);return tangle;}return  null;}}
public class Test6 {public static void main(String[] args) {Shape shape = Point1.PointXY(2,3,"Range");Shape shape1 = Point1.PointXY(3,4,"Tange");}}

在这里插入图片描述
看懂上述代码在来看创建线程池的方式就立刻明白
在这里插入图片描述
点开源码
在这里插入图片描述

三.线程池的参数

在这里插入图片描述1.int corePoolSize:核心线程数
ThreadPoolExecutor里面的线程个数并非是固定不变的,会根据当前的任务情况动态发生变化,corePoolSize至少得有这些线程,哪怕是你的线程池一点任务没有。

2.maximumPoolsize:最大线程数
ThreadPoolExecutor最多不能超过这些线程数,即使线程再忙。
3.longKeepAliveTime ,TimeUnit unit:最多等待时间,单位秒
当线程没有任务处理时,最多等待多少秒,等待时间一到如果还没有任务处理就会销毁。
4.BlockingQueue workQueue:线程内部有很多任务,这些任务可以使用阻塞队列来管理,线程池可以内置阻塞队列,也可以手动指定一个。
5.RejectedExecutionHandler handler:拒绝策略/拒绝方式(a,b,c,d)
a.线程池满了继续添加直接抛出异常,线程池之后不干活。
在这里插入图片描述
b.谁是添加这个新任务的线程,谁就去执行这个任务
在这里插入图片描述
c.丢弃最早的任务,执行新的任务
在这里插入图片描述
d.直接把新任务丢弃
在这里插入图片描述

四.线程池的实现

线程池计算斐波那契数列:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class Fib{public static int create(int n){if(n<=1){return 1;}return create(n-1)+create(n-2);}
}
public class Test8 {public static void main(String[] args) {ExecutorService executorService = Executors.newFixedThreadPool(4);for(int i=0;i<10;i++){final int num=i;executorService.submit(()->{System.out.println("第"+num+"个斐波那契数是:"+Fib.create(num)+",第"+num+"个线程是"+Thread.currentThread().getName());});}executorService.shutdown();}
}

在这里插入图片描述
从结果上看确实只是用到了4个线程去计算。

import java.util.concurrent.TimeUnit;public class Test9 {public static void main(String[] args) {RejectedExecutionHandler rejectedExecutionHandler = new ThreadPoolExecutor.AbortPolicy();ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(4,10,30, TimeUnit.SECONDS,new LinkedBlockingDeque<>(), rejectedExecutionHandler);for(int i=0;i<5;i++){threadPoolExecutor.submit(()->{System.out.println(Thread.currentThread().getName());});}}
}

在这里插入图片描述
#五.自我模拟线程池

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;class ThreadPool2 {BlockingQueue<Runnable> blockingQueue = new LinkedBlockingDeque<>();public void submit(Runnable runnable) throws InterruptedException {blockingQueue.put(runnable);}public ThreadPool2(int n) {for (int i = 0; i < n; i++) {Thread thread = new Thread(() -> {while (true) {try {blockingQueue.take().run();} catch (InterruptedException e) {throw new RuntimeException(e);}}});thread.start();}}
}public class Test11 {public static void main(String[] args) throws InterruptedException {ThreadPool2 threadPool = new ThreadPool2(4);for (int i = 0; i < 10; i++) {threadPool.submit(new Runnable() {@Overridepublic void run() {System.out.println("hello");}});}}
}

在这里插入图片描述

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

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

相关文章

[动态规划]---part2

前言 作者&#xff1a;小蜗牛向前冲 专栏&#xff1a;小蜗牛算法之路 专栏介绍&#xff1a;"蜗牛之道&#xff0c;攀登大厂高峰&#xff0c;让我们携手学习算法。在这个专栏中&#xff0c;将涵盖动态规划、贪心算法、回溯等高阶技巧&#xff0c;不定期为你奉上基础数据结构…

【学习】torchvision.datasets.ImageFolder()

在分类任务中&#xff0c;数据集文件存储往往是如下形式&#xff1a; - train- class1- image1.jpg- image2.jpg...- class2- image1.jpg- image2.jpg......此时&#xff0c;我们想要获取图片和标签&#xff0c;标签即为文件名&#xff08;class1、class2…&#xff09; 可以使…

【DevSecOps】2024 年需要警惕的 10 大 Web 应用程序安全威胁

【DevSecOps】2024 年需要警惕的 10 大 Web 应用程序安全威胁 由于 2023 年出现了许多创新,我们之前所了解的许多内容都发生了巨大变化;随着其中一些重大变化,威胁格局也发生了转变,一些旧威胁减少了,一些新威胁增加了。 技术每天都在不断变化,当我们谈论技术和相关威胁…

AI大模型:创新前沿的探索之路

AI大模型一直被视为人工智能领域的创新前沿&#xff0c;它们拥有强大的计算能力和学习能力&#xff0c;能够在各种复杂的任务中表现出色。随着技术的不断进步&#xff0c;越来越多的研究者和企业开始投入到AI大模型的研发和应用中&#xff0c;希望能够探索出更多的可能性。 在…

Tomcat基础与Nginx的动静分离

一、TOMCAT基础功能 &#xff08;一&#xff09;自动解压war包 在配置文件中讲到&#xff0c;当接受到请求后&#xff0c;会匹配符合要求的Host&#xff0c;在配置文件中的Host只有一个&#xff0c;且规定了自动解压war包 自动解压war包 .war&#xff1a;WebApp打包,类zip格…

stl的基本知识学习

1.vector&#xff1a; 2.set&#xff1a; 3.map&#xff1a; 4.栈&#xff1a; 5.队列&#xff1a; 6. unordered_map与unordered_set: 7. 位运算&#xff1a; 8.cctype&#xff1a; 导图&#xff1a;

ARM中专用指令(异常向量表、异常源、异常返回等)

状态寄存器传送指令 CPSR寄存器 状态寄存器传送指令:访问&#xff08;读写&#xff09;CPSR寄存器 读CPSR MRS R1, CPSR R1 CPSR 写CPSR MSR CPSR, #0x10 0x10为User模式&#xff0c;且开启IRQ和FRQ CPSR 0x10 在USER模式下不能随意修改CPSR&#xff0c;因为USER模式…

VMvare17安装centos8安装宝塔面板 教程

阿里镜像站&#xff1a;https://mirrors.aliyun.com/centos centos-8-isos-x86_64安装包下载_开源镜像站-阿里云 https://mirrors.aliyun.com/centos/8/isos/x86_64/CentOS-8.5.2111-x86_64-dvd1.iso 将上面的链接复制到迅雷进行高速下载 vmvare安装配置教程安装教程 CentOS…

动态规划(算法竞赛、蓝桥杯)--线性DP股票买卖含冷冻期

1、B站视频链接&#xff1a;E24 线性DP 股票买卖含冷冻期_哔哩哔哩_bilibili #include <bits/stdc.h> using namespace std; const int N100010; int w[N],f[N][3];int main(){int n;cin>>n;for(int i1;i<n;i)cin>>w[i];f[0][1]-1e7;f[0][0]-1e7;f[0][2]…

Django学习记录08——图表及文件上传案例

1.图表Echarts的应用 Apache ECharts 1.1 使用方法 引用echarts.js即可到官方文档中查询使用 1.2 常用图标的使用 图表展示页面的部署&#xff08;主要展示折线图、柱状图、饼图&#xff09; {% block content %}<div class"container"><div class&qu…

Docker安装MySQL镜像实战分享

今天我们对Docker安装MySQL镜像进行实战分享&#xff0c;以更深入的了解容器的使用场景。我们在云付服务器Ubuntu环境上已经安装好了Docker&#xff0c;接下来我们开始安装mysql5.7版本&#xff0c;安装mysql有两种思路&#xff0c;直接拉取mysql镜像和自己做mysql镜像&#xf…

对猫毛过敏还想养猫怎么办?除毛好的宠物空气净化器品牌推荐

许多朋友喜欢猫咪&#xff0c;但与猫咪相处一段时间后&#xff0c;他们可能会出现鼻塞、打喷嚏和眼泪不断的情况。让我们来科普一下如何让那些容易过敏的家人与猫咪更好地相处吧。为什么会过敏呢&#xff1f;因为猫咪的唾液中含有一种叫做Fel d1的蛋白质&#xff0c;通过舔毛散…

GEE 依照范围裁剪 下载Sentinel-2数据

0. GEE介绍 Google Earth Engine&#xff08;GEE&#xff09; 是由Google开发的一种云端平台&#xff0c;旨在提供强大的地理空间数据处理和分析工具。GEE集成了大量的遥感影像数据和地理空间数据集&#xff0c;以及高性能的计算资源&#xff0c;使用户能够在云端高效地进行大规…

GDB调试入门笔记

文章目录 What&#xff1f;WhyHow安装GDB安装命令查看是否安装成功调试简单的程序预备一个程序调试 使用breakinfolistnextprintstep一些小技巧在gdb前shell日志功能watch point| catch point 调试core调试一个运行的程序 What&#xff1f; GDB是什么&#xff1f; 全称GNU sym…

1、MQ_介绍、优缺点、类型等

MQ介绍 1. MQ概述 MQ&#xff08;Message Queue&#xff09;&#xff1a;消息队列&#xff0c;是基础数据结构中FIFO&#xff08;first in first out&#xff09;的一种数据结构。一般用来解决流量削峰、应用解耦、异步处理等问题&#xff0c;实现高性能&#xff0c;高可用&a…

鸿蒙实战开发:数据交互【RPC连接】

概述 本示例展示了同一设备中前后台的数据交互&#xff0c;用户前台选择相应的商品与数目&#xff0c;后台计算出结果&#xff0c;回传给前台展示。 样例展示 基础信息 RPC连接 介绍 本示例使用[ohos.rpc]相关接口&#xff0c;实现了一个前台选择商品和数目&#xff0c;后台…

【大数据】-- 创建 Paimon 外部表

如今&#xff0c;在数据湖三剑客&#xff08;delta lake、hudi、iceberg&#xff09;之上&#xff0c;又新出一派&#xff1a; apache paimon。我们恰好在工作中遇到&#xff0c;以下介绍在 dataworks 上&#xff0c;使用 maxcompute odps sql 创建 apache paimon 外部表的一些…

Claude3深夜震撼发布!模型特点分析,附使用教程

Claude3深夜震撼发布&#xff01;模型特点分析&#xff0c;附使用教程 引言 最新发布的Claude3引起了广泛关注&#xff0c;这次发布一举推出了三个不同类型的模型&#xff0c;分别是Claude 3 Haiku、Claude 3 Sonnet和Claude 3 Opus。每个模型都具有独特的特点和能力&#xff…

深色系可视化界面看腻了,来点浅色系?安排,20页来了。

只要不放在大屏上展示&#xff0c;贝格前端工场还是非常推崇浅色系的可视化界面&#xff0c;把它作为配色的首选 。浅色系可视化界面具有以下几个优势&#xff1a; 清晰明了 浅色系界面通常使用明亮的颜色&#xff0c;如白色、浅灰色等&#xff0c;使界面元素更加清晰可见。这…

Python 开发图形界面程序

用 Python 语言开发图形界面的程序&#xff0c;有2种选择&#xff1a; Tkinter 基于Tk的Python库&#xff0c;这是Python官方采用的标准库&#xff0c;优点是作为Python标准库、稳定、发布程序较小&#xff0c;缺点是控件相对较少。 PySide2/PySide6 基于Qt 的Python库&#x…