关于线程池

        线程池是一种多线程处理方式,通过将任务添加到队列中,在创建线程后自动启动这些任务。线程池中的线程可以复用,可以控制最大并发数,并且方便管理,也就是说,线程池会提前创建好一些线程,当后续需要用到线程时,从线程池里拿就行,一旦任务结束,线程并不会结束,而是回归到线程池,等待下一个任务,然后继续执行。那么为什么不什么时候使用线程就什么时候创建线程呢?这样不比往线程池里面拿线程更香吗?这是错误的,使用线程池显然更香,因为使用线程池比从系统里面创建新的线程更快更高效。为什么呢?因为如果是从系统这里直接创建线程,需要调用系统api,进一步的由操作系统内核,完成线程的创建过程,但是,由于内核是为所有的线程服务的,什么时候创建线程由系统内核决定,如果在系统内核繁忙时创建,则需要等待一定的时间使得内核有空闲时在创建,因此它是不可控的,而如果是从线程池这里获取线程,上述的内核中进行的操作,都是提前做好的,就算系统繁忙,也可以直接获取线程,不需要等待,因为它是直接创建好的,现在取线程的过程,纯粹的用户代码完成(纯用户态),它则是可控的。线程池有三种创建方式:单一线程池、固定大小线程池和可伸缩线程池。单一线程池只有一个线程,固定大小线程池指定了线程池的大小,而可伸缩线程池可以根据需要动态改变线程池的大小。线程池的核心组成是线程和任务,线程是前面学过的线程,任务是实现了Runnable或Callable接口的实例对象。线程池的代码实现可以使用Executor框架中的Executors类来创建,也可以使用ThreadPoolExecutor类来自定义线程池。

ExecutorService service = Executors.newFixedThreadPool(4);//ExecutorService service是线程池的对象,通过Executors里的方法来创建,创建了有4个线程的线程池。
ExecutorService service1 = Executors.newCachedThreadPool();//创建线程动态变化的线程池,已经创建了的线程不会回收。
ExecutorService service2 = Executors.newSingleThreadExecutor();//创建只有单个线程的线程池,与直接创建线程相比,更为方便。

线程池通过submit来添加任务,参数为Runnable对象,

service.submit(new Runnable() {@Overridepublic void run() {System.out.println("haha");}
});

除此之外,标准库还提供了一个接口更为丰富的线程池类:ThreadPoolExecutor,上述的线程池创建方法,其实是对ThreadPoolExecutor的各个不同的创建方法而进行的封装。

        ThreadPoolExecutor有多个构造方法,但只需要掌握这一个,就可以掌握所有的构造方法,这一个构造方法就是

public ThreadPoolExecutor(int corePoolSize,//核心线程数int maximumPoolSize,//最大线程数long keepAliveTime,//线程最大空闲时间TimeUnit unit,//时间单位BlockingQueue<Runnable> workQueue,//管理任务的阻塞队列ThreadFactory threadFactory,//ThreadFactory threadFactory是线程工厂,可以通过它来创建线程RejectedExecutionHandler handler)//拒绝方式

首先得知道,ThreadPoolExecutor类的线程池里的线程个数并不是一成不变的,而是会根据当前任务的情况动态发生变化,但这样的变化也是有限制的,corePoolSize和maximumPoolSize就是对里面线程数目的限制,其中corePoolSize表示核心线程数,也就是最少线程数,而maximumPoolSize则表示最大线程数,任你任务再多,创建的线程数目也不能超过这个数目。当空闲的时候,又会回收掉创建的线程,但线程数目不能少于核心线程数,这样就能保证繁忙时能高效的处理问题,空闲时也不会浪费资源。long keepAliveTime和TimeUnit unit则表示允许线程空闲的时间,其中keepAlive是时间数字,如3000,而unit则是单位,如(秒,毫秒之类的),当线程空闲时间超过这个时间后,则会对该线程进行回收,避免浪费资源。BlockingQueue<Runnable> workQueue则是要执行的任务,线程池中有很多任务,它们可以使用阻塞队列来进行管理,这个阻塞队列既可以是线程池内置的,也可以是手动指定的,如根据优先级来指定一个优先级队列。ThreadFactory threadFactory是线程工厂,可以通过它来创建线程,可以通过不同ThreadFactory来来创建不同的线程。RejectedExecutionHandler handler是这里的重点,它的含义是拒绝方式或者拒绝策略。当阻塞队列满了后,继续添加任务,该如何应对,你或许会问:让它在这里等待不就好了吗?这样的方法可行,但并不适合所有情况,因此,得需要一个确切的方式,以下就是拒绝方式。

1)ThreadPoolExecutor.AbortPolicy:当阻塞队列满了之后,如果继续添加,那么就会抛出异常,线程池直接不干了,不仅先前的任务不干了,新添加的任务也不干了。

2)ThreadPoolExecutor.CallerRunsPolicy:谁是添加这个任务的线程,谁去执行这个任务。

3)ThreadPoolExecutor.DiscardOldestPolicy:丢弃最早的任务,执行新的任务。

4)ThreadPoolExecutor.DiscardPolicy:丢弃新的任务。

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

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

相关文章

rabbitMQ (1)

文章目录 1. RabbitMQ 介绍1.1 几个重要概念1.2 RabbitMq 的工作原理 2 RabbitMQ 安装3. RabbitMQ 入门操作3.1 添加依赖3.2 生产者代码3.3 消费者代码 4. Work Queues5. 管理端页面创建队列 1. RabbitMQ 介绍 引用 &#xff1a; RabbitMQ 是一个消息中间件&#xff1a;它接受…

Xilinx FPGA 程序固化重新上电程序不运行的问题

问题描述 FPGA直接下载bit文件,功能正常。 FPGA擦除FLASH,烧写FLASH,正常。 电源断电,重新上电,FALSH里面的程序没有启动,FPGA程序没有跑起来。–FLASH启动不正常。 解决办法 在XDC约束文件里边增加约束: ## Configuration options, can be used for all designs se…

JsonPath详解

JsonPath 简介 JsonPath是一种信息抽取类库&#xff0c;是从JSON文档中抽取指定信息的工具文档 http://goessner.net/articles/JsonPath 安装 pip install jsonpath 使用 注意&#xff1a;这里的json_data为python数据&#xff0c;如列表&#xff0c;字典 data jsonpath.…

[Linux入门]---Linux项目自动化构建工具-make/Makefile

目录 1.背景2.make指令输入make默认为Makefile文件第一条指令执行Makefile文件对gcc指令特殊处理及原理特殊符号 3.总结 1.背景 会不会写makefile&#xff0c;从一个侧面说明了一个人是否具备完成大型工程的能力一个工程中的源文件不计数&#xff0c;其按类型、功能、模块分别放…

CNN(九):Inception v3算法实战

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客 &#x1f356; 原作者&#xff1a;K同学啊|接辅导、项目定制 1 理论基础 Inception v3论文 Inception v3由谷歌研究员Christian Szegedy等人在2015年的论文《Rethinking the Inception Architecture f…

Jmeter集成到jenkins

Jmeter集成到Jenkins Jmeter集成到Jenkins. 1 软件下载... 4 一:环境配置... 4 1.JDK安装&#xff1a;... 4 配置JDK环境变量... 5 2.Jmeter安装&#xff1a;... 5 配置jmeter环境变量... 6 3.安装Ant 7 配置Ant环境变量... 7 4.Git安装&#xff1a;... 8 配置git环境…

C++笔试

数据大小 #define ll long long int 最大值&#xff1a;21,4748,3647 int 最小值&#xff1a;-2147483648 float 最大值&#xff1a;3.40282e38 float 最小值&#xff1a;1.17549e-38 double 最大值&#xff1a;1.79769e308 double 最小值&#xff1a;2.22507e-308 long 最…

Untiy UDP局域网 异步发送图片

同步画面有问题&#xff0c;传图片吧 using System.Text; using System.Net.Sockets; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; using System.Net; using System; using System.Threading.Tasks; using Sy…

java内嵌浏览器CEF-JAVA、jcef、java chrome

java内嵌浏览器CEF-JAVA、jcef、java chrome jcef是老牌cef的chrome内嵌方案&#xff0c;可以进行java-chrome-h5-桌面开发&#xff0c;下面为最新版本&#xff08;2023年9月22日10:33:07&#xff09; JCEF&#xff08;Java Chromium Embedded Framework&#xff09;是一个基于…

Cesium 空间量算——生成点位坐标

文章目录 需求分析1. 点击坐标点实现2. 输入坐标实现 需求 用 Cesium 生成点位坐标&#xff0c;并明显标识 分析 以下是我的两种实现方式 第一种是坐标点击实现 第二种是输入坐标实现 1. 点击坐标点实现 //点位坐标getLocation() {this.hoverIndex 0;let that this;this.view…

板子接线图

1.ST-LINK V2接线 2.对抗板子刷蓝牙固件 接USB转TTL&#xff0c;用镊子短接两个孔 2.对抗板子用串口测试蓝牙AT命令 短接白色箭头&#xff0c;接TX&#xff0c;RX&#xff0c;电源

brpc 学习(一)M1 MacOS构建方法

tags: brpc categories: brpc 写在前面 实习阶段初次接触到 RPC 这样一种协议, 以及 brpc 这样一个很棒的框架, 但是当时没时间认真深入学习, 就是围绕使用 demo 开发, 还是有点不知其所以然的, 最近抽空来学习一下 brpc, 首要的一点就是在开发机上构建项目, 并且能够跑起来,…

Debezium系列之:Debezium采集Mysql数据库,数据库时间字段值的变化

Debezium系列之:Debezium采集Mysql数据库,数据库时间字段值的变化 一、背景二、创建时间字段表三、设置数据库时区四、UTC时区时间字段值变化五、北京时区时间字段值变化一、背景 Debezium使用UTC时区来发出时间列,可以通过使用 CustomConverter来使用任意时区发出时间列。使…

MongoDB【部署 04】Windows系统实现MongoDB多磁盘存储

Windows系统实现多磁盘存储 1.为什么2.多磁盘存储2.1 数据库配置2.2 文件夹磁盘映射2.3 创建新的数据集 3.总结 1.为什么 这里仅针对只有一台Windows系统服务器的情景&#xff1a; 当服务器存储不足时&#xff0c;或者要接入更多的数据&#xff0c;就会挂载新磁盘&#xff0c…

边缘计算AI智能安防监控视频平台车辆违停算法详解与应用

随着城市车辆保有量呈现高速增长趋势&#xff0c;交通拥堵、违章行为也日益泛滥。因为车辆未停放在指定区域导致的车位浪费、占用/堵塞交通要道、车辆剐蹭等问题层出不穷。通过人工进行违法停车的监控&#xff0c;不仅让监控人员工作负荷越来越大&#xff0c;而且存在发现不及时…

信息化发展51

部署交付 1 、软件开发完成后&#xff0c; 必须部署在最终用户的正式运行环境&#xff0c; 交付给最终用户使用&#xff0c; 才能为用户创造价值。 2 、软件部署是一个复杂过程&#xff0c; 包括从开发商发放产品&#xff0c; 到应用者在他们的计算机上实际安装并维护应用的所…

Lua学习笔记:词法分析

前言 本篇在讲什么 Lua的词法分析 本篇需要什么 对Lua语法有简单认知 对C语法有简单认知 依赖Visual Studio工具 本篇的特色 具有全流程的图文教学 重实践&#xff0c;轻理论&#xff0c;快速上手 提供全流程的源码内容 ★提高阅读体验★ &#x1f449; ♠ 一级标题…

SpringAOP补充-通知获取类型

JoinPoint 是 ProceedingJoinPoint 的父类。 getArgs()是JoinPoint获取原方法返回值的函数。 preceed()是ProceedingJoinPoint获取原方法返回值的函数。

【Java】Servlet API

Servlet API HttpServlet核心方法Servlet生命周期 HttpServletRequest核心方法 HttpServletResponse核心方法 HttpServlet 我们写 Servlet 代码的时候, 首先第一步就是先创建类, 继承自 HttpServlet, 并重写其中的某些方法. 核心方法 方法名称调用时机init在 HttpServlet 实…

近三年各领域数字孪生相关政策汇编(可下载)

自2021年国家“十四五”规划纲要提出“探索建设数字孪生城市”以来&#xff0c;国家发展和改革委员会、工业和信息化部、住房和城乡建设部、水利部、农业农村部等部门纷纷出台政策&#xff0c;大力推动数字孪生在千行百业的落地发展。这些政策不仅为数字孪生的应用提供了广阔的…