线程池--JAVA

虽然线程是轻量级进程,但是如果当创建和销毁的的频率非常之高,那么它也就会消耗很多的资源。

而线程池就是用来优化线程频繁创建和销毁的场景,减少线程创建、销毁的频率。

ExecutorService

JAVA标准库为我们实现了线程池,ExecutorService是一个接口,线程池的创建并不像平常的接口实现那样直接new,而是使用了“工厂模式”。

public static void main(String[] args) {//创建有4个线程的线程池ExecutorService service = Executors.newFixedThreadPool(4);//创建一个可以根据任务数量 来自行调整线程数量 的线程池ExecutorService service1 = Executors.newCachedThreadPool();//创建含有一个线程的线程池ExecutorService service2 = Executors.newSingleThreadExecutor();//创建一个含有3个线程的线程池,该线程池可以调度命令在给定时间后延迟运行ScheduledExecutorService service3 = Executors.newScheduledThreadPool(3);
}

创建好了之后可以利用submit()方法来给里面添加任务

public static void main(String[] args) {//创建有4个线程的线程池ExecutorService service = Executors.newFixedThreadPool(4);//添加5个任务for (int i = 0; i < 5; i++) {int a = i;service.submit(()->{System.out.println(a);});}
}

但是第四种创建线程池的方法有点特殊如果你想要实现延时执行任务就需要使用schedule

()方法。

public static void main(String[] args) {// 创建一个定时执行任务的线程池,设置核心线程数为3ScheduledExecutorService service = Executors.newScheduledThreadPool(3);//打印当前时间System.out.println(System.currentTimeMillis());// 定时执行任务,延迟2秒后开始执行service.schedule(() -> {// 执行的任务逻辑System.out.println("任务执行时间:" + System.currentTimeMillis());}, 2, TimeUnit.SECONDS);
}

上述这几个创建线程池的方法本质上都是将ThreadPoolExecutor进行了封装。

ThreadPoolExecutor

这个类有4中构造方法,可是仔细看就会发现前三种还是调用的的四种,所以本质上是只有一种。

各个参数的含义

corePoolSize

当前线程池中的核心线程数即当前线程池在空闲时含有的线程数量,也就是当前线程池包含的线程最少数量。

maximumPoolSize

当前线程池中允许存在的最大线程数。

keepAliveTime

当实际线程数大于核心线程数时,多余的空闲线程能够存活的最长时间。

unit

存活时间的单位。

NANOSECONDS:千分之一微秒;

MICROSECONDS:千分之一毫秒;

MILLISECONDS:千分之一秒;

SECONDS:秒;

MINUTES:分钟;

HOURS:小时;

DAYS:天;

workQueue

用于保存待执行任务的队列。

threadFactory

创建新线程时所用的工厂类。

handler

当线程池中的任务满了之后所使用的拒绝策略。

ThreadPoolExecutor.AbortPolicy:直接抛出异常;

ThreadPoolExecutor.CallerRunsPolicy:新添加的任务,由添加任务的线程执行;

ThreadPoolExecutor.DiscardOldestPolicy :丢弃队列中最老的任务,再将新任务添加进任务队列;

ThreadPoolExecutor.DiscardPolicy:丢弃新添加的任务。

线程池的关闭

想要关闭线程池需要使用shutdown()方法

public static void main(String[] args) {// 创建一个定时执行任务的线程池,设置核心线程数为3ScheduledExecutorService service = Executors.newScheduledThreadPool(3);//打印当前时间System.out.println(System.currentTimeMillis());// 定时执行任务,延迟2秒后开始执行service.schedule(() -> {// 执行的任务逻辑System.out.println("任务执行时间:" + System.currentTimeMillis());}, 2, TimeUnit.SECONDS);
}

可以看出任务执行完后程序并没有退出。

public static void main(String[] args) {// 创建一个定时执行任务的线程池,设置核心线程数为3ScheduledExecutorService service = Executors.newScheduledThreadPool(3);//打印当前时间System.out.println(System.currentTimeMillis());// 定时执行任务,延迟2秒后开始执行service.schedule(() -> {// 执行的任务逻辑System.out.println("任务执行时间:" + System.currentTimeMillis());}, 2, TimeUnit.SECONDS);//主线程休眠一段时间try {Thread.sleep(2000); // 休眠2秒} catch (InterruptedException e) {e.printStackTrace();}// 关闭线程池service.shutdown();
}

接下来为了更好的理解线程池,下面是模拟实现一个含有固定线程数的线程池。

模拟实现

先创建一个类名为MyThreadPool里面含有一个属性,类型为BlockingQueue。

public class MyThreadPool {//队列大小为5private BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(5);
}

写一个只有一个参数的有参构造方法,参数为线程池的线程数。

利用循环创建n个线程,每个线程都不断地从队列中拿任务。

public MyThreadPool(Integer n) {for (int i = 0; i < n; i++) {Thread t = new Thread(()->{while(true) {try {Runnable runnable = queue.take();runnable.run();} catch (InterruptedException e) {throw new RuntimeException(e);}}});t.start();}
}

写一个submit()方法可以给队列中添加任务。

public void submit(Runnable runnable) {try {this.queue.put(runnable);} catch (InterruptedException e) {throw new RuntimeException(e);}
}

此时一个简单的线程池就完成了,下面来进行一下简单的测试:

public static void main(String[] args) {MyThreadPool myThreadPool = new MyThreadPool(5);for (int i = 0; i < 40; i++) {int a = i;myThreadPool.submit(()->{System.out.println(a);});}
}

完整代码

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;//线程池
public class MyThreadPool {private BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(5);public MyThreadPool(Integer n) {for (int i = 0; i < n; i++) {Thread t = new Thread(()->{while(true) {try {Runnable runnable = queue.take();runnable.run();} catch (InterruptedException e) {throw new RuntimeException(e);}}});t.start();}}public void submit(Runnable runnable) {try {this.queue.put(runnable);} catch (InterruptedException e) {throw new RuntimeException(e);}}
}

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

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

相关文章

windows11上安装虚拟机VMware

1、安装虚拟机&#xff08;待补充&#xff09; 第二步&#xff1a;安装VMware tools 实现windows文件上传到虚拟机中 1、安装好虚拟机后&#xff0c;查看虚拟机ip用Xshell连接虚拟机&#xff0c;并安装VMware tools(只有安装了VMware tools才能实现虚拟机和本机的文件共享。在…

无人机航迹规划(四):七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划(提供MATLAB代码)

一、七种算法&#xff08;DBO、LO、SWO、COA、LSO、KOA、GRO&#xff09;简介 1、蜣螂优化算法DBO 蜣螂优化算法&#xff08;Dung beetle optimizer&#xff0c;DBO&#xff09;由Jiankai Xue和Bo Shen于2022年提出&#xff0c;该算法主要受蜣螂的滚球、跳舞、觅食、偷窃和繁殖…

Python编辑开发---pycharm pro 2023 中文

PyCharm Pro 2023是一款功能强大的Python集成开发环境&#xff08;IDE&#xff09;&#xff0c;旨在提高Python开发人员的生产力。它提供了智能代码编辑、实时代码分析和调试工具&#xff0c;支持版本控制和数据库工具&#xff0c;以及可扩展的插件系统。PyCharm Pro 2023可在多…

什么是区块链?

区块链 区块链 &#xff08;英语&#xff1a;blockchain&#xff09;是借由 密码学 与 共识机制 等技术建立&#xff0c;存储数据的 保证不可篡改和不可伪造的 分布式技术。 什么是区块 区块 就是将一批数据打包在一起&#xff0c;并且给打包出来的区块编号。第一个区块的编…

Kylin 安装novnc 远程访问

noVNC可以使用浏览器直接访问服务器&#xff0c;而不需要使用VNC客户端。 1.初始环境 关闭防火墙或允许IP访问本机 2.安装依赖 dnf install -y tigervnc-server git 3.git下载novnc git clone https://github.com/novnc/noVNC.git git clone https://gitee.com/yangyizhao…

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK使用相机日志跟踪功能(C++)

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK使用相机日志跟踪功能&#xff08;C&#xff09; Baumer工业相机Baumer工业相机NEOAPI SDK和短曝光功能的技术背景Baumer工业相机通过NEOAPI SDK使用相机日志跟踪功能1.引用合适的类文件2.通过NEOAPI SDK使用相机日志跟踪功能3.通…

如何用数据赋能社媒营销决策?

在数字化时代&#xff0c;越来越多的商家开始意识到数据分析对于改善经营的重要性。 传统决策更多依赖过往经验、商业直觉、他人的思路模板等方法&#xff0c;或者依靠描述性统计、简单的数据分析。在数字时代&#xff0c;则通过精细化数据分析&#xff0c;做出更明智的营销决策…

S2-08 ESP-IDF开发 : 存储

S2-06 和 S2-07 暂时先不发&#xff0c;课上没给同学们将&#xff0c;分别是 DMA 和 USB 章节&#xff0c;作为专项讲 存储 ESP32 系列芯片中&#xff0c;不同型号的芯片所携带的 ROM、SRAM、RCT SRAM、PSRAM 以及 Flash大小不同&#xff0c;他们的作用如下&#xff1a; SRAM…

2023年总结我所经历的技术大变革

&#x1f4e2;欢迎点赞 &#xff1a;&#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff0c;赐人玫瑰&#xff0c;手留余香&#xff01;&#x1f4e2;本文作者&#xff1a;由webmote 原创&#x1f4e2;作者格言&#xff1a;新的征程&#xff0c;我们面对的不仅…

如何使用支付宝沙箱环境本地配置模拟支付并结合内网穿透远程调试

文章目录 前言1. 下载当面付demo2. 修改配置文件3. 打包成web服务4. 局域网测试5. 内网穿透6. 测试公网访问7. 配置二级子域名8. 测试使用固定二级子域名访问 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的 人工智能学习网站&#xff0c; 通俗易懂&#xff…

基本查找(顺序查找)

基本查找/顺序查找 基本思想思路代码示例输出结果 ​ 说明&#xff1a;顺序查找适合于存储结构为数组或者链表。 基本思想 顺序查找也称为线形查找&#xff0c;属于无序查找算法。从数据结构线的一端开始&#xff0c;顺序扫描&#xff0c;依次将遍历到的结点与要查找的值相比…

linux基础学习(5):yum

yum是为了解决rpm包安装依赖性而产生的一种安装工具 1.yum源 1.1配置文件位置 yum源的配置文件在/etc/yum.repos.d/中 *Base源是网络yum源&#xff0c;也就是需要联网才能使用的yum源。默认情况下&#xff0c;系统会使用Base源 *Media源是光盘yum源&#xff0c;是本地yum源…

【Android12】Android Framework系列---Adb和PMS安装apk源码流程

Adb和PMS安装apk源码流程 adb install命令 通过adb install命令可以将apk安装到Android系统&#xff08;注意&#xff1a;特定类型的apk&#xff0c;比如persist类型是无法通过adb安装的&#xff09; 下述命令中adb解析install命令&#xff0c;并调用Android PackageManagerS…

Java实现大学计算机课程管理平台 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 实验课程档案模块2.2 实验资源模块2.3 学生实验模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 实验课程档案表3.2.2 实验资源表3.2.3 学生实验表 四、系统展示五、核心代码5.1 一键生成实验5.2 提交实验5.3 批阅实…

【Android】app中阻塞的looper为什么可以响应touch事件

这里&#xff0c;我们考虑一个问题&#xff0c;Android中的应用是一个looper线程&#xff0c;没有任务时就阻塞着&#xff0c;其他线程通过handler调用等方式向主线程looper发送任务&#xff0c; 如果点击应用上的按钮&#xff0c;应用是怎么及时响应的呢&#xff0c; 是专门启…

Redis(01)——常用指令

基础指令 select 数字&#xff1a;切换到其他数据库flushdb&#xff1a;清空当前数据库flushall&#xff1a;清空所有数据库dbsize&#xff1a;查看数据库大小exists key1[key2 …]&#xff1a;判断当前的key是否存在keys *&#xff1a;查看所有的keyexpire key 时间&#xff…

终端(命令提示符或Windows PowerShell或Azure Cloud Shell)概述

终端&#xff08;命令提示符或Windows PowerShell或Azure Cloud Shell&#xff09;是一种很 不 好用的东西 就是要背&#xff0c;很 不 爽 介绍 Windows 终端是一个新式主机应用程序&#xff0c;它面向你喜爱的命令行 shell&#xff0c;如命令提示符、PowerShell 和 bash&…

《GitHub Copilot 操作指南》课程介绍

第1节&#xff1a;GitHub Copilot 概述 一、什么是 GitHub Copilot 什么是 GitHub Copilot GitHub Copilot是GitHub与OpenAI合作开发的编程助手工具&#xff0c;利用机器学习模型生成代码建议。它集成在开发者的集成开发环境&#xff08;IDE&#xff09;中&#xff0c;可以根…

新买电脑配置不低却卡顿?

目录 前言&#xff1a; 电脑卡顿的原因 Windows 10必做的系统优化 禁用 IP Helper 关闭系统通知 机械硬盘开启优化驱动器功能 开启存储感知 前言&#xff1a; 新买的电脑配置不低&#xff0c;但却卡顿甚至程序不反应&#xff0c;这是怎么回事儿&#xff1f; 其实并不…

使用人工智能助手 Github Copilot 进行编程 01

本章涵盖了 AI 助⼿如何改变新程序员的学习⽅式为什么编程永远不会再⼀样了AI 助⼿如 Copilot 的⼯作原理Copilot 如何解决⼊⻔级编程问题AI 辅助编程的潜在危险 在本章中&#xff0c;我们将讨论人类如何与计算机进行交流。我们将向您介绍您的 AI 助手 GitHub Copilot&#x…