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

Java多线程(三)——线程池及定时器

线程池就是一个可以复用线程的技术。前面三种多线程方法就是在用户发起一个线程请求就创建一个新线程来处理,下次新任务来了又要创建新线程,而创建新线程的开销是很大的,这样会严重影响系统的性能。线程池就相当于预先创建好几个线程(招聘几个打工人),来分配之后要处理的任务(干活)

线程池的接口:ExecutorService

线程池对象

  1. 使用ExecutorService的实现类ThreadPoolExecutor自创建一个线程池对象

可以看到有7个参数,通过这些参数设置线程池的规模和特征。ExecutorService的常用方法有execute、submit、shutdown、shutdownNow。

  1. ThreadPoolExecutor构造器的参数:

  1. 1:指定线程池的线程数量(核心线程): corePoolSize

  1. 2:指定线程池可支持的最大线程数: maximumPoolSize

  1. 3:指定临时线程的最大存活时间: keepAliveTime

  1. 4:指定存活时间的单位(秒、分、时、天): unit

  1. 5:指定任务队列: workQueue

  1. 6:指定用哪个线程工厂创建线程: threadFactory

  1. 7:指定线程忙,任务满的时候,新任务来了怎么办: handler,默认丢弃任务并抛出RejectedExecutionException异常。

  1. ThreadPoolExecutor创建线程池对象

ExecutorService pool=new ThreadPoolExecutor(3,6,8, TimeUnit.SECONDS,new ArrayBlockingQueue<>(6), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
  1. 线程池处理Runnable任务 ——pool.execute()

首先实现Runnable接口,重写run方法。然后创建MyRunnable任务对象,只不过这里不是把MyRunnable任务对象交给Thread处理,而是使用线程池pool的execute()方法。

class myRunnable implements Runnable{@Overridepublic void run() {for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + " ——>" + i);}try {System.out.println(Thread.currentThread().getName() + " —— 休眠");Thread.sleep(2000);System.out.println(Thread.currentThread().getName() + " —— 启动");} catch (InterruptedException e) {e.printStackTrace();}}
}
//Runnable target=new myRunnable();pool.execute(target);
  1. 线程池处理Callable任务 ——pool.submit()

定义类实现Callable接口,重写call方法,封装要做的事情。然后把Callable对象进行submit(),并且可以返回执行后的结果。

class myCallable implements Callable<String> {private int n;public myCallable(int n) {this.n = n;}@Overridepublic String call() throws Exception {int s=0;for (int i = 0; i < n; i++) {s+=n;}return Thread.currentThread().getName()+" 1+...+" + n +", 子线程执行结果: "+s;}
}
//Callable myCallable=new myCallable(10);Future<String> f1 = pool.submit(myCallable);System.out.println(f1.get());
  1. 使用Executors(线程池的工具类)调用方法返回不同特点的线程池对象

Executors的底层其实也是基于线程池的实现类ThreadPoolExecutor创建线程池对象的。Executors得到线程池对象的常用方法:

方法

说明

弊端

public static ExecutorService newCachedThreadPool()

线程数量随着任务增加而增加,如果线程任务执行完毕且空闲了一段时间则会被回收掉。

允许创建的线程数量最大上限是Integer.MAX_VALUE,非常非常大

可能会创建大量线程,出现OOM错误( 内存溢出 java.lang.OutOfMemoryError )

public static ExecutorService newFixedThreadPool(int nThreads)

创建固定线程数量的线程池,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程替代它。

允许请求的任务队列长度是Integer.MAX_VALUE,可能会堆积大量请求,出现OOM错误

public static ExecutorService newSingleThreadExecutor ()

创建只有一个线程的线程池对象,如果该线程出现异常而结束,那么线程池会补充一个新线程。

允许请求的任务队列长度是Integer.MAX_VALUE,可能会堆积大量请求,出现OOM错误

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)

创建一个线程池,可以实现在给定的延迟后运行任务,或者定期执行任务。

允许创建的线程数量最大上限是Integer.MAX_VALUE,

可能会创建大量线程,出现OOM错误

Executors不适合做大型互联网场景的线程池方案,建议使用ThreadPoolExecutor来指定线程池参数,这样可以明确线程池的运行规则,规避资源耗尽的风险。

  1. 定时器

定时器是一种控制任务延时调用,或者周期调用的技术。定时器的实现方式有两种:

方式一:Timer。创建Timer定时器对象,然后开启定时器。这是一种单线程方法,处理多个任务按照顺序执行,存在延时与设置定时器的时间有出入。可能因为其中的某个任务的异常使Timer线程死掉,从而影响后续任务执行。

    Timer t=new Timer();t.schedule(new TimerTask() {@Overridepublic void run() {System.out.println("定时器~");}},3000,3000);

方式二: ScheduledExecutorService定时器。基于线程池,某个任务的执行情况不会影响其他定时任务的执行。先得到线程池对象,然后再进行周期调度方法。

        ScheduledExecutorService pool=Executors.newScheduledThreadPool(3);pool.scheduleAtFixedRate(new TimerTask() {@Overridepublic void run() {System.out.println("定时器");}},3,3,TimeUnit.SECONDS);
  1. 并发与并行

CPU同时可以处理线程的数量有限,所以CPU会轮询为每个线程服务,只是由于CPU切换的速度很快,给我们的感觉这些线程在同时执行,其实可能只是并发。所以说多个线程其实是并发与并行同时进行的

  1. 线程的6种状态

NEW(新建)

线程刚被创建,但是并未启动。

Runnable(可运行)

线程已经调用了start()等待CPU调度。

Blocked(锁阻塞)

线程在执行的时候未竞争到锁对象,则该线程进入Blocked状态。

Waiting(无限等待)

一个线程进入Waiting状态,另一个线程调用notify或者notifyAll方法才能够唤醒。

Timed Waiting(计时等待)

同waiting状态,有几个方法有超时参数,调用他们将进入Timed Waiting状态。带有超时参数的常用方法有Thread.sleep 、Object.wait。

Teminated(被终止)

因为run方法正常退出而死亡,或者因为没有捕获的异常终止了run方法而死亡。

相关文章:

Java多线程(三)——线程池及定时器

线程池就是一个可以复用线程的技术。前面三种多线程方法就是在用户发起一个线程请求就创建一个新线程来处理&#xff0c;下次新任务来了又要创建新线程&#xff0c;而创建新线程的开销是很大的&#xff0c;这样会严重影响系统的性能。线程池就相当于预先创建好几个线程&#xf…...

Linux命令行安装Oracle19c教程和踩坑经验

安装 下载 从 Oracle官方下载地址 需要的版本&#xff0c;本次安装是在Linux上使用yum安装&#xff0c;因此下载的是RPM。另外&#xff0c;需要说明的是&#xff0c;Oracle加了锁的下载需要登录用户才能安装&#xff0c;而用户是可以免费注册的&#xff0c;这里不做过多说明。 …...

Linux常用命令等

目录 1.Linux常用命令 (1)系统命令 (2)文件操作命令 2.vim编辑器 3.linux系统中,软件安装 (1) rpm 安装,RedHat Package Manager (2)yum 安装 (3)源代码编译安装 1.Linux常用命令 Linux命令是非常多的,对于像嵌入式开发工程师,运维工程师需要掌握的命令是非常多的.对于…...

CEC2014:鱼鹰优化算法(Osprey optimization algorithm,OOA)求解CEC2014(提供MATLAB代码

一、鱼鹰优化算法简介 鱼鹰优化算法&#xff08;Osprey optimization algorithm&#xff0c;OOA&#xff09;由Mohammad Dehghani 和 Pavel Trojovsk于2023年提出&#xff0c;其模拟鱼鹰的捕食行为。 鱼鹰是鹰形目、鹗科、鹗属的仅有的一种中型猛禽。雌雄相似。体长51-64厘米…...

MyBatis底层原理【源码运行时序图】

MyBatis初始化流程&#x1f6f7; 以下代码为例&#x1f389; &#x1f387;可对应源码阅读 MyBatis初始化流程✨ #mermaid-svg-yoG1e8Dnp3UIAOUW {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-yoG1e8Dnp3UIAOU…...

k8s 系列之 CoreDNS 解读

k8s 系列之 CoreDNS CoreDNS工作原理 kuberntes 中的 pod 基于 service 域名解析后&#xff0c;再负载均衡分发到 service 后端的各个 pod 服务中&#xff0c;如果没有 DNS 解析&#xff0c;则无法查到各个服务对应的 service 服务 在 Kubernetes 中&#xff0c;服务发现有几…...

从测试鸡蛋硬度到跳表的设计

我回忆起六七年前的一道题鸡蛋掉落问题&#xff0c;有幸在leetCode上找到题目了 原题是2枚鸡蛋 leetCode有拓展&#xff0c;k枚鸡蛋 具体的思路是这样的。 以2枚鸡蛋验证100层为例 不能直接二分查找&#xff0c;因为你在50层测试时&#xff0c;如果直接鸡蛋碎了&#xff0c;那…...

3D立体视觉成像原理介绍【一 】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言什么是基线&#xff1f;基线是如何影响3D图像质量激光三角测量飞行时间结构光相机时间编码结构光前言 本文将介绍3D立体视觉的成像原理&#xff0c;包括【激光三…...

CEC2021:鱼鹰优化算法(Osprey optimization algorithm,OOA)求解CEC2021(提供MATLAB代码

一、鱼鹰优化算法简介 鱼鹰优化算法&#xff08;Osprey optimization algorithm&#xff0c;OOA&#xff09;由Mohammad Dehghani 和 Pavel Trojovsk于2023年提出&#xff0c;其模拟鱼鹰的捕食行为。 鱼鹰是鹰形目、鹗科、鹗属的仅有的一种中型猛禽。雌雄相似。体长51-64厘米…...

0301_对应的南京比特物联网

0301_对应的南京比特物联网目录概述需求&#xff1a;设计思路实现思路分析1.流程拓展实现性能参数测试&#xff1a;参考资料和推荐阅读Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better …...

钡铼技术BL302 ARM工控机QT图形化界面开发的实践

QT是一种跨平台的应用程序框架&#xff0c;用于开发图形用户界面(GUI)、网络应用程序和嵌入式应用程序。QT提供了丰富的GUI组件和工具&#xff0c;使开发人员能够轻松地创建专业级别的应用程序。QT使用C编写&#xff0c;支持多种操作系统&#xff0c;包括Windows、Linux、macOS…...

Python try except异常处理详解(入门必读)

Python 中&#xff0c;用try except语句块捕获并处理异常&#xff0c;其基本语法结构如下所示&#xff1a; try:可能产生异常的代码块 except [ (Error1, Error2, ... ) [as e] ]:处理异常的代码块1 except [ (Error3, Error4, ... ) [as e] ]:处理异常的代码块2 except [Exc…...

信息系统基本知识(三)软件工程

1.4 软件工程 定义&#xff1a;将系统的、规范的、可度量的工程化方法应用于软件开发、运行和维护的全过程即上述方法的研究 软件工程由方法、工具和过程三个部分组成 1.4.1 需求分析 软件需求是指用户对新系统在功能、行为、性能、设计约束等方面的期望。 需求层次 业务…...

Linux下软件部署安装管理----rpmbuild打包rpm包部署安装

来源&#xff1a;微信公众号「编程学习基地」 文章目录1.安装rpmbuild2.rpm包制作打包rpm包3.rpm包安装4.rpm包卸载1.安装rpmbuild yum install rpmbuild yum install rpmdevtools创建rpm包管理路径&#xff0c;生成rpm相关目录 RPM打包的时候需要编译源码&#xff0c;还需要…...

ThreadLocal学会了这些,你也能和面试官扯皮了!

前言 我们都知道,在多线程环境下访问同一个共享变量,可能会出现线程安全的问题,为了保证线程安全,我们往往会在访问这个共享 变量的时候加锁,以达到同步的效果,如下图所示。 对共享变量加锁虽然能够保证线程的安全,但是却增加了开发人员对锁的使用技能,如果锁使用不当…...

【存储】存储特性

存储特性精简配置技术&#xff08;SmartThin&#xff09;SmartThin主要功能容量虚拟化存储空间写时分配&#xff1a;Capacity-on-Write读写重定向&#xff1a;Direct-on-Time应用场景及配置流程存储分层技术&#xff08;SmartTier&#xff09;存储分层工作原理关键技术容量初始…...

Qt使用OpenGL进行多线程离屏渲染

基于Qt Widgets的Qt程序&#xff0c;控件的刷新默认状况下都是在UI线程中依次进行的&#xff0c;换言之&#xff0c;各个控件的QWidget::paintEvent方法会在UI线程中串行地被调用。若是某个控件的paintEvent很是耗时&#xff08;等待数据时间CPU处理时间GPU渲染时间&#xff09…...

Vue基础入门讲义(三)-指令

文章目录1.什么是指令&#xff1f;2.插值表达式2.1.花括号2.2.插值闪烁2.3.v-text和v-html3.v-model4.v-on4.1.基本用法4.2.事件修饰5.v-for5.1.遍历数组5.2.数组角标5.3.遍历对象6.key7.v-if和v-show7.1.基本使用7.2.与v-for结合7.3.v-else7.4.v-show8.v-bind8.1. 属性上使用v…...

pod资源限制,探针(健康检查)

pod资源限制&#xff0c;探针&#xff08;健康检查&#xff09;一、资源限制当定义 Pod 时可以选择性地为每个容器设定所需要的资源数量。 最常见的可设定资源是 CPU 和内存大小&#xff0c;以及其他类型的资源当为 Pod 中的容器指定了 request 资源时&#xff0c;调度器就使用…...

Python | 蓝桥杯进阶第一卷——字符串

欢迎交流学习~~ 专栏&#xff1a; 蓝桥杯Python组刷题日寄 蓝桥杯进阶系列&#xff1a; &#x1f3c6; Python | 蓝桥杯进阶第一卷——字符串 &#x1f50e; Python | 蓝桥杯进阶第二卷——递归&#xff08;待续&#xff09; &#x1f49d; Python | 蓝桥杯进阶第三卷——动态…...

【Perplexity Pro深度评测】:20年AI工具实战专家拆解3大隐藏成本与5个被忽略的高阶功能值不值得?

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Perplexity Pro订阅值不值得 核心能力对比&#xff1a;免费版 vs Pro版 Perplexity Pro 提供实时联网搜索、多文件上传解析&#xff08;PDF/DOCX/CSV&#xff09;、无限次深度追问及自定义AI工作区等关…...

Nitric常见问题解答:开发者最关心的25个问题汇总

Nitric常见问题解答&#xff1a;开发者最关心的25个问题汇总 【免费下载链接】nitric Nitric is a multi-language framework for cloud applications with infrastructure from code. 项目地址: https://gitcode.com/gh_mirrors/ni/nitric Nitric是一个多语言框架&…...

ElevenLabs Starter计划实战指南(新手必看的4步激活+2次配额翻倍技巧)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;ElevenLabs Starter计划的核心定位与适用边界 ElevenLabs Starter 计划是面向开发者、内容创作者及小型团队推出的免费语音合成入门方案&#xff0c;旨在以零门槛方式提供高质量、低延迟的文本转语音&…...

基于Rust构建AI智能体平台:架构设计与工程实践

1. 从零到一&#xff1a;构建你自己的AI智能体平台最近几年&#xff0c;大语言模型&#xff08;LLM&#xff09;的爆发式发展&#xff0c;让“智能体”&#xff08;Agent&#xff09;从一个学术概念&#xff0c;迅速变成了提升工作效率的利器。你可能用过一些现成的AI工具&…...

芯片设计人才培养:从Sondrel模式看产学合作如何弥合能力鸿沟

1. 项目背景与行业契机最近在整理行业资料时&#xff0c;翻到一篇十多年前的旧闻&#xff0c;讲的是英国一家名为Sondrel的系统级芯片设计咨询公司&#xff0c;与宁波诺丁汉大学合作&#xff0c;启动了一个针对中国学生的芯片设计人才培养项目。这件事发生在2013年&#xff0c;…...

频谱分析仪EMC预测试实战:30MHz-1GHz辐射发射定位与整改

1. 项目概述&#xff1a;用频谱分析仪搞定辐射发射预测试如果你是一名硬件工程师&#xff0c;或者正在和电磁兼容&#xff08;EMC&#xff09;问题作斗争&#xff0c;那么对30MHz到1000MHz这个频段的辐射发射测试一定不会陌生。这是绝大多数电子产品认证&#xff08;比如CE、FC…...

【OpenCV实战】从相机标定到PnP测距:手把手实现单目视觉定位(C++代码详解)

1. 相机标定基础与实战准备 单目视觉定位就像给机器人装上了一只"智慧之眼"&#xff0c;而相机标定就是教会这只眼睛如何正确理解世界。想象一下&#xff0c;如果你戴了一副度数不合适的眼镜&#xff0c;看到的物体位置和形状都会失真——相机标定要解决的就是类似的…...

开关电源EMC设计:从原理到实践的关键技术

1. 开关电源EMC设计基础 开关电源因其高效率和小型化优势&#xff0c;在现代电子设备中广泛应用。然而&#xff0c;高频开关动作带来的电磁干扰(EMI)问题不容忽视。作为一名电源工程师&#xff0c;我经常需要面对各种EMC挑战。记得有一次&#xff0c;我们团队设计的工业电源模块…...

全国跨省搬家专业靠谱无套路排行 跨省搬家公司选哪个物流平台便宜省心?哪个搬家公司专业安全保障,没有半路加价?

用户最担心的“半路加价”问题&#xff0c;几乎所有“搬家公司/搬家平台”每天都发生各样“半路加价”问题。本文根据各大社交平台用户避雷贴&#xff0c;统计出搬家公司/搬家平台专业靠谱无套路程度前5名&#xff0c;方便广大需要跨省搬家的用户&#xff0c;接近跨省搬家公司选…...

2026年国民技术数字IC笔试试卷带答案

满分:100分 时间:90分钟 一、单选题(每题3分,共30分) 1. 在静态时序分析(STA)中,建立时间检查的公式为( ) A. Tclk + Tskew ≥ Tck-q + Tlogic + Tsetup B. Tclk - Tskew ≥ Tck-q + Tlogic + Tsetup C. Tclk ≥ Tck-q + Tlogic - Tsetup D. Tlogic ≥ Tsetup + Tho…...