java线程池(ThreadPoolExecutor)实例讲解

GD32F303定时器配置:实现两路互补PWM输出与相位控制 本文详细解析了基于GD32F303定时器实现两路互补PWM输出与精确相位控制的方法。通过配置TIMER2的中间对齐模式,结合REMAP功能解决引脚复用问题,从硬件层面稳定生成相位差180度的互补PWM信号,适用于电机驱动、开关电源等对时序要求苛刻的应用场景。 阅读详情

在java中,如果我们要使用一个线程, 那么我们可以这样创建一个线程

  Thread thread= new Thread() {
				  @Override
				  public void run() {
				         l.add(random.nextInt());	  
				  }
			  };
			   thread.start();
然而这样做的坏处是, 每次都需要重新创建一个线程, 而非重复利用。 频繁的创建线程和销毁线程往往时间甚至要高于线程执行任务的时间。 那么有没有办法让这些线程可重复性的利用呢?   我的意思是, 让这些线程在执行完之后不销毁, 放在某一个地方。  达到可复用的目的呢?  答案是有的。 java中的 java.util.concurrent包中提供了线程池,来达到线程可复用的目的。  当然。 concurrent包中不止线程池 其中还包括了ConcurrentHashMap   BlockingQueue 等一系列线程安全的并发容器。


而java.util.concurrent.ThreadPoolExecutor 就是一个线程池。  他是一个Class、 签名如下:

 

public class ThreadPoolExecutor extends AbstractExecutorService {

    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,  BlockingQueue<Runnable> workQueue);
 
    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
            BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory);
 
    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
            BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler);
 
    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
        BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler);
    ...
}

共有四个构造方法:

              corePoolSize:核心池的大小,默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中。

  maximumPoolSize:线程池最大线程数, 表示在这个池中最多能够创建多少个线程。

keepAliveTime:    表示线程没有任务执行时最多保持多久时间会终止。 注意  默认情况下,只有当线程池中的线程数大于corePoolSize时,keepAliveTime才会起作用,直到线程池中的线程数不大于corePoolSize,即当线程池中的线程数大于corePoolSize时,如果一个线程空闲的时间达到keepAliveTime,则会终止,直到线程池中的线程数不超过corePoolSize。但是如果调用了allowCoreThreadTimeOut(boolean)方法,在线程池中的线程数不大于corePoolSize时,keepAliveTime参数也会起作用,直到线程池中的线程数为0;

unit:参数keepAliveTime的时间单位,有7种取值。 具体查看文档。

 

workQueue: 存储等待执行任务的线程, 提供一个队列进行管理任务线程。 基本的任务队列有几种比如:无界队列    有界队列.

这里需要注意的是:在创建ThreadPoolExecutor初期,线程并不会立即启动。而是等到有任务提交时才启动。 除非你显示调用perstartAllCoreThreads方法。


下面我在我的电脑上写了一个不算严格的测试。 来计算使用线程池和不使用线程池的时间消耗。

import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPool {
	
	 private static int count=2000;
	 public void yes_threadpool() {
		 
    long startTime = System.currentTimeMillis();
     final List<Integer> l= new LinkedList<Integer>();
     ThreadPoolExecutor tP= new ThreadPoolExecutor(1,60,1,TimeUnit.SECONDS,
    		 new  LinkedBlockingQueue<Runnable>(count));
         final Random random= new Random();
         for (int i = 0; i <count; i++) {
			 tP.execute(new Runnable() {
				
				@Override
				public void run() {
					// TODO Auto-generated method stub
					 l.add(random.nextInt());
				}
			});
		}
         tP.shutdown();
         
         try {
			tP.awaitTermination(1,TimeUnit.DAYS);
		} catch (Exception e) {
			// TODO: handle exception
			 System.out.println("线程池异常");
			 e.printStackTrace();
		}
   
          System.out.println(System.currentTimeMillis()-startTime);
          System.out.println(l.size());
         
    }
	 
	 
	 public void no_threadpool() {
		 long startTime = System.currentTimeMillis();
		 final List<Integer> l = new LinkedList<Integer>();
		  final Random random= new Random();
		 for(int i=0; i<count; i++) {
			  Thread thread= new Thread() {
				  @Override
				  public void run() {
				         l.add(random.nextInt());	  
				  }
			  };
			   thread.start();
			   
			 try {
				thread.join();
			} catch (InterruptedException e) {
				// TODO: handle exception
			   System.out.println("非线程池异常");
			   e.printStackTrace();
			}  
		 }
		  System.out.println(System.currentTimeMillis()-startTime);
		  System.out.println(l.size());
	 }
	 
	 public static void main(String[] args) {
		 ThreadPool threadPool = new ThreadPool();
		 
		// threadPool.yes_threadpool(); 21
		 
		//threadPool.no_threadpool(); 1049
		 
		 /*
		  *  测试结果为 使用线程池 21  不使用线程池 1049
		  *
		  */
	}
}
大家可以分别测试使用线程池和没使用线程池的时间差别。  在我的电脑上 使用线程池只用了21毫秒。  不使用线程池用了1049毫秒。 我的jdk版本是1.8

当然这只是并发包中提供的一种线程池。 另外还有其中有几种。 如newCachedThreadPool       newFixedThreadPool  等。 他们都是由Executors提供。

其中: newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。 而 new FixedThreadPool 创建一个定长线程池,它可控制线程最大并发数(可以控制最大并发数, 比如说csdn对于下载资源就有并发控制),超出的线程会在队列中等待。.

最近刚好有点空闲时间就做个总结。  关于java.util.concurrent并发包, 只能说。 很强大。












     



Arduino ESP32S3开发环境搭建 ------ 在线下载安装包Failed解决方案 本文介绍了Arduino ESP32 S3开发环境搭建的离线解决方案。 阅读详情

相关推荐

MT4-EA自动化交易研究笔记(2022-04-22)

自从接触到mt4的EA自动化交易,更让我这个10多年的老程序员看到了曙光,目前来看也确实出了一点成果,只是是否能稳定盈利有待时间的考验,所以开此专栏,一来做做记录与分析,更好的优化我的EA,二来也希望能与更多的高手交流,以完善我的交易系统

t35254056的博客 2291

java线程池案例

简介 线程Thread是一个重量级资源,线程的创建、启动以及销毁都是比较耗费系统资源的,同时受限于系统资源的限制,线程的数量与系统性能是一种抛物线的关系,因此对线程的管理,是一种非常好的程序设计习惯,自JDK1.5起,utils包提供了ExecutorService[ɪɡˈzɛkjətɚ]线程池的实现。通俗的将:为了避免重复的创建线程,线程池的出现可以让线程进行复用。当有工作来,就会向线程池拿一个线程,当工作完成后,并不是直接关闭线程,而是将这个线程归还给线程池供其他任务使用。 一个线程池包括以下四个基

人生就像一场戏 1万+

用宝塔面板+CentOS 7.6,30分钟搞定DNF手游私服搭建(附全套资源下载)

本文详细介绍了如何使用宝塔面板和CentOS 7.6在30分钟内快速搭建DNF手游私服。通过图形化界面操作,无需复杂命令,即可完成服务端部署、MySQL数据库配置及客户端适配,适合Linux新手快速上手。

weixin_33737774的博客 611

Java线程池应用实例

线程池是多线程的一种处理方式,处理过程中将任务添加到队列中,线程创建完成后自动启动这些任务,任务就是实现了Runnable或Callable接口的实例对象。可以根据系统需求和硬件环境灵活控制线程的数量,对线程进行统一管理。3、12306网上购票。

Rsun2018的博客 6157

高通平台Android稳定性调试笔记:手把手教你用T32、Crash Utility分析Kernel Panic与RAM Dump

本文详细介绍了高通平台Android内核崩溃的分析方法,包括使用T32 Simulator和Crash Utility工具链解析Kernel Panic与RAM Dump。从环境配置、dump文件预处理到高级调试技巧,手把手教你如何定位和解决Android系统崩溃问题,特别适用于MSM/SA8155平台的开发者。

weixin_42543046的博客 529

交叉熵损失函数基本概念及公式

对于二分类问题,模型的输出通常是一个标量,表示样本属于正类的概率。因此,在二分类的交叉熵损失函数中,我们只需要考虑一个概率值,即模型预测为正类的概率。具体来说,当真实标签为1时,我们关注模型预测为正类的概率;当真实标签为0时,我们关注模型预测为负类的概率。因此,二分类的交叉熵损失函数可以表示为:其中,y 表示真实标签,取值为 0 或 1;p 表示模型预测为正类的概率。而对于多分类问题,模型的输出通常是一个向量,表示样本属于各个类别的概率。因此,在多分类的交叉熵损失函数中,我们需要考虑所有类别的概率。

qlkaicx的博客 1万+

Java多线程案例——线程池

Java多线程案例——线程池

如风暖阳的博客 1万+

AI Agent开发大全第二十课-如何开发一个MCP(从0开发一个MCP Server)

大模型的MCP火了,可是无论是Claude官网本身自带Sample还是全网任何一本教程没有一个可以真正应用在生产环境中的。要么就是只能在本地以文件IO流的方式运行要么干脆连编译都出错,真正的mcp server和client是怎么编写的?如何运行在分布式环境?本教程就带大家真正从0开始以“AI计算食物热量“为例带大家真正学习mcp开发的全过程。

打造全国最全的AI Agent开发知识领域的博客 1804

Java线程池使用样例

最近接触的项目,数据量都大的离谱,一些复杂的算法功能运行起来简直是灾难。话不多说,下面提供一种用线程池加快程序运行的样例参考,欢迎大家讨论指正。

如果是雨天,你会想起我 2219

《Python星球日记》 第43天:机器学习概述与Scikit-learn入门

《Python星球日记》 第43天:机器学习概述与Scikit-learn入门

Code_流苏:在代码中寻诗意,在实践中觅真知 934

RSL-RL:开源人形机器人强化学习控制研究库

摘要:RSL-RL是一款专为机器人领域设计的开源强化学习库,其核心特点是紧凑性、可修改性和高性能。该库聚焦PPO和BC两大主流算法,并整合了对称性增强、好奇心驱动等机器人专用技术。通过纯GPU训练优化,RSL-RL在大型仿真中展现出卓越的吞吐性能,已成功应用于腿足运动控制、全身协调等多个机器人研究场景。其轻量级架构包含运行器、算法和网络三个可独立修改的组件,支持TensorBoard等主流日志工具。该框架特别适合需要快速原型开发的机器人研究者,但不适用于通用机器学习基准测试。开源地址:https://git

2506_90492529的博客 1680

JAVA基础:线程池的使用

线程池是一种常见的多线程编程技术,它允许我们在系统中使用一个固定数量的线程来执行任务,以免过多的线程拉低了系统的性能。在本文中,我们将探讨线程池的使用和一些最佳实践,以便在您的代码中获得更好的性能和可维护性。

拾一二的博客 5187

国科大学习资料--人工智能原理与算法-2020年期末考试题解析(学长整理)

国科大学习资料–人工智能原理与算法-2020年期末考试题解析 张文生老师主讲 试卷共有6道题,题目不难,希望大家能取得好的成绩。 3.9 传教士和野人问题。三个传教士和三个野人在河的一岸,有一条能载一个人或者两个人的船。请设法使所有人都渡到河的另一岸,要求在任何地方野人数都不能多于传教士的人数。这个问题在AI领域中很有名,是因为它是第一个从分析的观点探讨问题形式化的论文的主题(Amarel,1968)。 a. 请对该问题进行详细形式化,只描述确保该问题求解所必需的特性。画出完整的状态空间图。 b. 应用合适

无名何许人的博客 4789

【Java多线程】ThreadPoolExecutor线程池讲解

背景 如果我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。 那么有没有一种办法使得线程可以复用,就是执行完一个任务,并不被销毁,而是可以继续执行其他的任务? 在Java中可以通过线程池来达到这样的

elricboa的专栏 1883

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Java并发工具ThreadPoolExecutor线程池使用讲解2

既然选择这个行业,选择了做一个程序员,也就明白只有不断学习,积累实战经验才有资格往上走,拿高薪,为自己,为父母,为以后的家能有一定的经济保障。学习时间都是自己挤出来的,短时间或许很难看到效果,一旦坚持下来了,必然会有所改变。不如好好想想自己为什么想进入这个行业,给自己内心一个答案。面试大厂,最重要的就是夯实的基础,不然面试官随便一问你就凉了;其次会问一些技术原理,还会看你对知识掌握的广度,最重要的还是你的思路,这是面试官比较看重的。

2401_84411776的博客 1257

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Java并发工具ThreadPoolExecutor线程池使用讲解1

小编在这里分享些我自己平时的学习资料,由于篇幅限制,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!程序员代码面试指南 IT名企算法与数据结构题目最优解这是” 本程序员面试宝典!书中对IT名企代码面试各类题目的最优解进行了总结,并提供了相关代码实现。针对当前程序员面试缺乏权威题目汇总这一-痛点, 本书选取将近200道真实出现过的经典代码面试题,帮助广“大程序员的面试准备做到万无一失。“刷”完本书后,你就是“题王”!

2401_83329718的博客 882

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

线程池的使用场景以及java中ThreadPoolExecutor类的讲解

目录 为什么要使用线程池? Java中的线程池 workQueue参数分析 handler参数分析 execute方法与submit方法 合理的选择线程池大小 为什么要使用线程池? 对于java初学者来说,首先接触到的创建线程的方法就是new Thread,或者实现Runnable接口,重写run方法来实现多线程。虽然简单,但是一句话:谁来帮你管理线程??? 若不使用线程池:...

γìńɡ雄尐年ぐ的博客 9988

java对象池 线程池_java线程池对象ThreadPoolExecutor的深入讲解

使用线程池的好处1、降低资源消耗可以重复利用已创建的线程降低线程创建和销毁造成的消耗。2、提高响应速度当任务到达时,任务可以不需要等到线程创建就能立即执行。3、提高线程的可管理性线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一分配、调优和监控ThreadPoolExecutor 介绍:java 提供的线程池类;ThreadPoolExecutor ...

weixin_34342091的博客 266

[转发]线程池的使用场景以及java中ThreadPoolExecutor类的讲解

转发:https://blog.youkuaiyun.com/qq_26012495/article/details/84325445 为什么要使用线程池? 对于java初学者来说,首先接触到的创建线程的方法就是new Thread,或者实现Runnable接口,重写run方法来实现多线程。虽然简单,但是一句话:谁来帮你管理线程??? 若不使用线程池: 1、线程的创建销毁都要自己来完成 2、没有统一的管理,若每次请求都开启多个线程,无限制的请求袭来,可能造成资源耗尽 3、不够灵活 线程池的出现能让你双手游离于多线程之外

mlh1551799812的博客 626

Java实现4种线程池以及自定义线程池ThreadPoolExecutor示例讲解

一、线程池简介 1. 线程池的概念:           所谓的线程池指的就是多个线程封装在一起进行操作。使用线程池可以很好地提高性能,线程池在系统启动时即创建大量空闲的线程,程序将一个任务传给线程池,线程池就会启动一条线程来执行这个任务,执行结束以后,该线程并不会死亡,而是再次返回线程池中成为空闲状态,等待执行下一个任务。 2. 线程池的工作机制          2.1 在线程池的编程...

付冰冰的博客 1223

Java并发工具ThreadPoolExecutor线程池使用讲解2(1)

对于面试,一定要有良好的心态,这位小伙伴面试美团的时候没有被前面阿里的面试影响到,发挥也很正常,也就能顺利拿下美团的offer。小编还整理了大厂java程序员面试涉及到的绝大部分面试题及答案,希望能帮助到大家,也祝愿大家都能够升职加薪!《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!取!

2401_83330193的博客 655

Java线程池ThreadPoolExecutor参数讲解、实例助记 保证你过目不忘

Java线程池ThreadPoolExecutor参数讲解、实例助记 保证你过目不忘

weixin_43275484的博客 982

java线程池使用详解ThreadPoolExecutor使用示例

一 使用线程池的好处 二 Executor 框架 2.1 简介 2.2 Executor 框架结构(主要由三大部分组成) 1) 任务(Runnable /Callable) 2) 任务的执行(Executor) 3) 异步计算的结果(Future) 2.3 Executor 框架的使用示意图 三 (重要)ThreadPoolExecutor 类简单介绍 3.1 ThreadPoolExecutor 类分析 3.2 推荐使用 ThreadPoolExecutor 构造函数创建线程池 四 ..

xu_yong_lin的博客 5万+

JAVA多线程之ThreadPoolExecutor创建线程池

线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。说明:Executors 返回的线程池对象的弊端如下:FixedThreadPool 和 SingleThreadPool:允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM。允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM。

lqr666的博客 4004

java线程池ThreadPoolExecutor详解及使用

java线程池ThreadPoolExecutor的使用 在日常开发中我们经常会使用多线程,但是当线程数量达到一定程度时,频繁的创建线程、执行任务、销毁线程就会造成资源的浪费和性能的开销,那么这个时候就要考虑使用线程池了,它可以很好的避免这个问题,尤其是程序中需要创建大量的生存周期很短的线程时,更应该考虑使用线程池。 线程池的概念 线程池(ThreadPool),简单的说,它就是一个装有线程的池子,我们只需把任务(多线程执行的内容)交给线程池来处理,和数据库连接池、Http连接池的概念差不多的,通过维护

weixin_44178366的博客 4617
上一篇: SpringMvc实现文件上传
下一篇: JAVA内存模型 (JMM)和同步以及可见性
zh_coder
博客等级 码龄12年 31粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值