Java SE入门及基础(62) 线程池 执行器

线程池

1. 执行器

        In all of the previous examples, there's a close connection between the task being done by a new thread, as defined by its Runnable object, and the thread itself, as defined by a Thread object. This works well for small applications, but in large-scale applications, it makes sense to separate thread management and creation from the rest of the application. Objects that encapsulate these functions are known as executors.
        在前面的所有示例中,由新线程(由其Runnable 对象定义)执行的任务与由 Thread 对象定义的线程本身之间存在紧密的联系。 这对于小型应用程序非常有效,但是在大型应用程序中,将线程管理和创建与其余应用程序分开是有意义的。 封装这些功能的对象称为执行器。
Executor接口方法
void execute ( Runnable command ); // 将任务添加到线程池中,等待线程池调度执行
ExecutorService接口常用方法
void shutdown (); // 有序关闭线程池,不再接收新的线程任务,但池中已有任务会执行
List < Runnable > shutdownNow (); // 关闭线程池,尝试停止所有正在执行的任务,并将池中等待执行的任务返回
boolean isShutdown (); // 检测线程池是否已经关闭
boolean isTerminated (); // 检测线程池是否已经终止
Future <?> submit ( Runnable task ); // 提交一个任务至线程池中

2.线程池

        Most of the executor implementations in java.util.concurrent use thread pools, which consist of worker threads. This kind of thread exists separately from the Runnable and Callable tasks it executes and is often used to execute multiple tasks.
        java.util.concurrent中的大多数执行程序实现都使用线程池,该线程池由工作线程组成。这种线程与它执行的Runnable Callable 任务分开存在,通常用于执行多个任务。
        Using worker threads minimizes the overhead due to thread creation. Thread objects use a significant amount of memory, and in a large-scale application, allocating and deallocating many thread objects creates a significant memory management overhead.
        使用工作线程可以最大程度地减少线程创建所带来的开销。线程对象占用大量内存,在大型应用程序中,分配和取消分配许多线程对象会产生大量内存管理开销。
        One common type of thread pool is the fixed thread pool. This type of pool always has a specified number of threads running; if a thread is somehow terminated while it is still in use, it is automatically replaced with a new thread. Tasks are submitted to the pool via an internal queue, which holds extra tasks whenever there are more active tasks than threads.
        线程池的一种常见类型是固定线程池。这种类型的池始终具有指定数量的正在运行的线程。如果某个线程在仍在使用时以某种方式终止,则它将自动替换为新线程。任务通过内部队列提交到池中,该内部队列在活动任务多于线程时容纳额外的任务。
        An important advantage of the fixed thread pool is that applications using it degrade gracefully.
        固定线程池的一个重要优点是使用该线程池的应用程序可以正常降级
线程池构造方法
public ThreadPoolExecutor ( int corePoolSize , // 核心线程数
int maximumPoolSize , // 最大线程数
long keepAliveTime , // 工作线程存活时间
TimeUnit unit , // 时间单位
BlockingQueue < Runnable > workQueue , // 任务队列
ThreadFactory threadFactory , // 线程工厂
RejectedExecutionHandler handler ) // 拒绝处理器
示例
import java.util.Queue;
import java.util.concurrent.*;
public class ThreadPoolTest {public static void main(String[] args) {LinkedBlockingDeque<Runnable> taskQueue = new LinkedBlockingDeque<>(10);ThreadPoolExecutor pool = new ThreadPoolExecutor(5, //核心线程数10, //最大工作线程数2,//非核心线程的工作线程存活时间TimeUnit.SECONDS,//存活时间单位taskQueue,//任务队列Executors.defaultThreadFactory(),//线程池中的线程创建工厂new ThreadPoolExecutor.AbortPolicy());//拒绝新线程任务的策略for(int i=0; i<30; i++){pool.submit(new ThreadPoolTask(i));int corePoolSize = pool.getCorePoolSize();//获取核心线程数int size = pool.getQueue().size(); //获取队列中任务个数long finish = pool.getCompletedTaskCount();//获取线程池执行完成任务的个数System.out.printf("线程池中核心线程数:%d,队列中任务个数:%d,线程池完成任务数:%d\n",corePoolSize, size, finish);try {Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}}pool.shutdown();//关闭线程池,等待线程池中的任务执行完成,但是不会接收新的线程任务}static class ThreadPoolTask implements Runnable{private int num;public ThreadPoolTask(int num) {this.num = num;}@Overridepublic void run() {System.out.println("正在执行线程任务" + num);try {Thread.sleep(400);} catch (InterruptedException e) {e.printStackTrace();}}}
}
线程池工作流程
        线程池启动后,核心线程就已经启动,当一个新的任务提交到线程池时,首先会检测当前是否存在空闲的核心线程,如果存在,就将该任务交给这个空闲核心线程执行。如果不存在,那么就将该任务交给队列,在队列中排队等候。如果队列满了,此时线程池会检测当前工作线程数是否达到最大线程数,如果没有达到最大线程数,那么将由线程工厂创建新的工作线程来执行队列中的任务,这样,队列中就有空间能够容纳这个新任务。如果创建的工作线程在执行完任务后,在给定的时间范围内没有新的任务执行,这些工作线程将死亡。如果已经达到最大线程数,那么线程池将采用提供的拒绝处理策略来拒绝这个新任务。
线程池创建方式
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExecutorTest {public static void main(String[] args) {
//创建一个给定核心线程数以及最大线程数的线程池,该线程池队列非常大ExecutorService pool1 = Executors.newFixedThreadPool(5);
//创建只有一个核心线程数以及最大线程数的线程池,该线程池队列非常大ExecutorService pool2 = Executors.newSingleThreadExecutor();
//创建一个核心线程为0,最大线程数为整数的最大值的可缓存的线程池ExecutorService pool3 = Executors.newCachedThreadPool();
//创建一个给定核心线程数,最大线程数为整数的最大值的可调度的线程池ExecutorService pool4 = Executors.newScheduledThreadPool(5);}
}

3. 线程池的使用

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ExecutorTaskTest {public static void main(String[] args) {ExecutorService service = Executors.newFixedThreadPool(5);for (int i = 0; i < 100; i++) {int order = i;service.submit(() -> System.out.println("正在执行任务" + order));}service.shutdown();}
}

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

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

相关文章

Golang | Leetcode Golang题解之第212题单词搜索II

题目&#xff1a; 题解&#xff1a; type Trie struct {children map[byte]*Trieword string }func (t *Trie) Insert(word string) {node : tfor i : range word {ch : word[i]if node.children[ch] nil {node.children[ch] &Trie{children: map[byte]*Trie{}}}nod…

Zynq系列FPGA实现SDI视频编解码,基于GTX高速接口,提供5套工程源码和技术支持

目录 1、前言工程概述免责声明 2、相关方案推荐本博已有的 SDI 编解码方案本方案在Xilinx--Kintex系列FPGA上的应用 3、详细设计方案设计原理框图SDI 输入设备Gv8601a 均衡器GTX 解串与串化SMPTE SD/HD/3G SDI IP核BT1120转RGB图像缓存视频读取控制HDMI输出RGB转BT1120Gv8500 驱…

vuepress使用简介及个人博客搭建

目录 一、介绍二、环境准备三、安装运行vuepress四、目录结构五、配置文件六、导航栏配置七、导航栏logo八、浏览器图标九、侧边栏配置十、添加 Git 仓库和编辑链接十一、部署到GitHub十二、搭建成功 一、介绍 VuePress 是 Vuejs 官方提供的一个是Vue驱动的静态网站生成器&…

Qt 配置ASan

Qt 配置ASan 文章目录 Qt 配置ASan摘要关于ASan&#xff08;AddressSanitizer&#xff09;在Qt中配置 ASan1. 安装必要的工具2. 修改项目的 .pro 文件3. 重新构建项目4. 运行应用程序5. 分析错误报告示例注意事项 关键字&#xff1a; Qt、 ASan、 AddressSanitizer 、 GCC …

CTFHUB-SSRF-Redis协议

本题需要用到&#xff1a; 在线编码网址&#xff1a;https://icyberchef.com/ gopherus工具&#xff1a;https://mp.csdn.net/mp_blog/creation/editor/139440201 开启题目&#xff0c;页面空白 和上一个题FastCGI协议一样&#xff0c;还是使用gopherus攻击redis ./gopheru…

Oracle PL / SQL 插入insert 第二部分

DUAL表 dual是由具有一列和一行的oracle数据库&#xff08;所有者SYS&#xff09;拥有的表。 要评估1 1的添加&#xff0c;请执行以下SQl SELECT语句&#xff1a; SELECT 1 1 FROM dual; 快速找出oracle如何评估你对内置函数length&#xff08;&#xff09;的使用。 SELE…

vlan基础相关

7.2以太网交换基础 数据链路层也叫2层网络&#xff0c;用的是Mac地址&#xff0c;想到Mac地址就要想到交换机。 以太网协议&#xff08;LAN&#xff09;以太网是建立在CSMA/CD载波监听多路访问/冲突检测&#xff0c;机制上的广播型网络。CSMA工作原理是先监听&#xff0c;在介…

110kV以下变电所电力监控-安科瑞电力监控解决方案

一、系统介绍 变电站电力监控系统为110kV及以下用户变电站提供了完整的SCADA功能。 二、系统硬件 AM5SE系列微机保护装置 全电参量测量 谐波制动独立操作回路 可编程出口矩阵&#xff1b;定制化的逻辑设计&#xff1b;故障录波&#xff1b;事件记录、故障 录波数据&#x…

在UniApp中使用Three.js渲染3D模型

在移动应用开发中,3D渲染正变得越来越普遍。本文将介绍如何在UniApp框架中集成Three.js库来渲染3D模型,为您的应用增添引人注目的视觉效果。 1. 简介 UniApp是一个跨平台开发框架,允许开发者使用Vue.js开发一次,就能发布到iOS、Android、Web等多个平台。Three.js则是一个强大…

3099. 哈沙德数 Easy

如果一个整数能够被其各个数位上的数字之和整除&#xff0c;则称之为 哈沙德数&#xff08;Harshad number&#xff09;。给你一个整数 x 。如果 x 是 哈沙德数 &#xff0c;则返回 x 各个数位上的数字之和&#xff0c;否则&#xff0c;返回 -1 。 示例 1&#xff1a; 输入&a…

高内聚低耦合举个例子详细介绍

学习目标&#xff1a; 高内聚低耦合举个例子详细介绍 学习内容&#xff1a; 高内聚和低耦合是软件设计中的两个重要原则&#xff0c;旨在提高系统的可维护性、可扩展性和灵活性。下面我们通过一个例子详细介绍高内聚和低耦合的概念及其实现方法。 例子&#xff1a;在线购物系…

聊天交友系统开发专业语聊交友app开发搭建同城交友开发婚恋交友系统相亲app开发

1、上麦相亲互动:直播间内除了红娘外&#xff0c;还有男女用户两个视频麦位&#xff0c;直播间符合要求的用户可以申请上麦 2、公屏聊天:为上麦用户可以通过在公屏发言的方式参与直播间内的话题互动。 3、私信,异性用户之间可以发送私信消息&#xff0c;通过付费或开通会员可解…

法国工程师IMT联盟 密码学及其应用 2023年期末考试补考题

1 JAVA 安全 1.1 问题1 1.1.1 问题 用 2 或 3 句话解释 Java 执行模型&#xff08;Java 虚拟机machine virtuelle Java)&#xff09;中引入introduit沙箱bac sable机制 mcanisme d’excution par isolation的目的。 1.1.2 问题解释 在 Java 执行模型&#xff08;Java 虚拟机…

知识见闻 - 什么是SAT求解器

SAT求解器&#xff08;SAT solver&#xff0c;布尔可满足性问题求解器&#xff09;是一种计算工具&#xff0c;用于确定是否存在一个变量赋值&#xff0c;使给定的布尔公式为真。布尔可满足性问题是计算理论中的一个重要问题&#xff0c;通常用来解决逻辑推理、验证和优化问题。…

Java面试八股文

一、Redis 1. 使用场景 &#xff08;1&#xff09;Redis的数据持久化策略有哪些 RDB&#xff1a;全称Redis Database Backup file&#xff08;Redis数据备份文件&#xff09;&#xff0c;也被叫作Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故…

【信息系统项目管理师】18年~23年案例概念型知识

文章目录 18上18下19上19下20上20下21上21下22年上22年下23年上 18上 请简述 ISO 9000 质量管理的原则 领导作用、 过程方法、 管理的系统方法、 与供方互利的关系、 基于事实的决策方法、 持续改进、 全员参与、 以顾客为关注焦点 概念 国家标准(GB/T 1 9000 2008)对质量的定…

JS如何把年月日转为时间戳

在JavaScript中&#xff0c;将年月日&#xff08;通常表示为一个字符串或者分别的年、月、日数字&#xff09;转换为时间戳&#xff08;即Unix时间戳&#xff0c;是自1970年1月1日&#xff08;UTC/GMT的午夜&#xff09;开始所经过的秒数&#xff0c;不考虑闰秒&#xff09;可以…

【proteus经典实战】VB上位机程序控制DS1302时钟的proteus仿真

一、简介&#xff1a; VB上位机程序控制DS1302时钟是一种常见的应用&#xff0c;DS1302是一款实时时钟芯片&#xff0c;通常用于计算机、电子设备或其他系统中&#xff0c;以提供时间戳和其他时间相关功能&#xff0c;DS1302时钟芯片通常需要外部电源供电&#xff0c;并且具有…

嵌入式c语言2——预处理

在c语言中&#xff0c;头部内容&#xff0c;如include与define是不参与编译而直接预先处理的 如include相当于把头文件扩展&#xff0c;define相当于做了替换 c语言大型工程创建时&#xff0c;会有调试版本与发行版本&#xff0c;发行时不希望看到调试部分内容&#xff0c;此时…

基于多视点编码光场的全景三维重建方法

欢迎关注GZH《光场视觉》 摘要&#xff1a;在基于光场的一系列应用中&#xff0c;目标的三维重建是基础且关键的任务。普通光场只能重建单一视角而无法重建全景&#xff0c;并且在纹理特征匮乏的区域也无法生成准确的三维信息。针对以上问题&#xff0c;提出一种基于多视点编码…