详解Java线程池

线程池的实现(JAVA) 很多人仅仅了解过线程池的强大,确没有亲自动手去实现。在这里提供一份用JAVA写的实例代码,供大家参考。 立即下载

前言:线程池技术是通过对线程资源的统一管理来达到对线程资源的重复利用,降低线程频繁创建和销毁的开销。java jdk在java.util.concurrent并发包中有一套现成的对线程池的实现方案,我们可以直接拿来使用,快速实现多线程并发编程场景。这里对concurrent包中的线程池框架的实现进行一些分析。

Java线程池使用代码示例

public class Test {
    public static void main(String[] args) throws Exception {
        Task task1 = new Task(1);
        Task task2 = new Task(2);

//        ExecutorService normalExecutor = new ThreadPoolExecutor(2, 4, 200, TimeUnit.MILLISECONDS,
//                new ArrayBlockingQueue<Runnable>(5));
//        ExecutorService singleExecutor = Executors.newSingleThreadExecutor();
//        ExecutorService cachedExecutor = Executors.newCachedThreadPool();
        //创建线程池服务
     ExecutorService executor = Executors.newFixedThreadPool(2);
     //将任务交给线程池执行
        executor.execute(task1);
        executor.execute(task2);
        executor.shutdown();
    }
}

//可以提交给线程池执行的任务类,线程池执行任务时会执行其中的run方法
class Task implements Runnable {
    private int taskNum;

    public Task(int num) {
        this.taskNum = num;
    }

    public void run() {
        System.out.println("开始执行任务:" + taskNum);
        try {
            Thread.currentThread().sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("结束执行任务:" + taskNum);
    }
}

执行结果如下:

从结果可以看出后提交给线程池的任务先执行了。所以执行execute方法时只是将任务提交给线程池去管理,任务的执行顺序是由线程池内部去协调的。

java线程池实现原理

java线程池的核心实现类是ThreadPoolExecutor,该类的继承关系如下:

最底层其实现的接口Executor的定义如下:

public interface Executor {
    void execute(Runnable command);
}

可以看到,该接口只有一个方法execute,ThreadPoolExecutor实现该方法后,通过该方法的调用将任务提交给线程池。所以ThreadPoolExecutor.execute里的逻辑就是线程池执行任务的密码所在。

这里先关注下ThreadPoolExecutor类中如下几个比较重要的常量

//记录当前线程池中工作线程的数量
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
//将一个整形的32位分为两部分,高3位和低29位
private static final int COUNT_BITS = Integer.SIZE - 3;
//将整形的低29位用于存储工作线程数,所以可开启的最大线程数为2的29次方
private static final int CAPACITY   = (1 << COUNT_BITS) - 1;

//将整形的高3位用于存储线程池的当前状态值
private static final int RUNNING    = -1 << COUNT_BITS;
private static final int SHUTDOWN   =  0 << COUNT_BITS;
private static final int STOP       =  1 << COUNT_BITS;
private static final int TIDYING    =  2 << COUNT_BITS;
private static final int TERMINATED =  3 << COUNT_BITS;

ThreadPoolExecutor里很多地方使用了类似的位运算的方式进行状态值的存储和逻辑运算来提高运行效率

现在看下ThreadPoolExecutor类的构造函数,构造函数的参数揭示了线程池的核心变量:

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

这里涉及的几个核心变量解释如下:

  • corePoolSize:核心线程数,线程池运行稳定后维持的线程数
  • maximumPoolSize:最大线程数,线程池最多可以使用的线程数
  • keepAliveTime:超时时间,线程在该超时时间间隔内从任务队列未获取到任务时,若线程池工作线程数超过corePoolSize,则关闭当前线程,且线程池线程数减1
  • unit:keepAliveTime使用的时间单位
  • workQueue:任务存放的队列
  • threadFactory:线程工厂,线程池使用该工厂类的方法产生线程
  • handler:当线程池中线程数已达最大值,且任务队列已满,无法处理新加入的任务时。由自定义的handler处理该任务

ThreadPoolExecutor.execute对任务的处理流程如下图:

ThreadPoolExecutor.execute的执行示意图如下:

通过ThreadPoolExecutor构造函数的参数,我们发现如果我们要通过ThreadPoolExecutor创建一个适合我们业务场景的线程池,需要对ThreadPoolExecutor的运行原理和几个核心参数有比较深入的理解。线程池的设计者在这方面也做了一定的考虑,在concurrent包中,提供了一个有用的工具类Executors,这个类提供了一些工厂方法可以帮助我们简单方便的创建出适用于各种场景的线程池,有些方法就是对ThreadPoolExecutor做了简单的封装。其中,业务上比较常用到的获取线程池的工厂方法有如下几个:

//创建固定大小的线程池,在并发任务比较多的场景中比较常用
public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}

//创建一个单线程化的线程池,线程池只使用一个线程执行所有的任务,可以保证任务的执行顺序
public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}

//创建一个可缓存线程池,队列只能存放一个元素,任务会及时被线程处理,适用于对任务处理的及时性要求比较高的场景
public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}

喜欢这篇文章的朋友可以点个赞

针对于上面所涉及到的知识点我总结出了有1到5年开发经验的程序员在面试中涉及到的绝大部分架构面试题及答案做成了文档和架构视频资料免费分享给大家(包括Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并发等架构技术资料),希望能帮助到您面试前的复习且找到一个好的工作,也节省大家在网上搜索资料的时间来学习,也可以关注我一下以后会有更多干货分享。

添加我的微信号 neteasestudy 即可免费获取Java架构学习资料哦!
欢迎加入我的微信群和大家一起讨论专研技术!群内技术点有里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatisNetty,Redis,Kfka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料,以及不定期的内推BAT企业!希望大家共同努力,构建一个自己的人脉交流圈!
 

 

 

 

java线程池实例 java线程池实例java线程池实例E:\Users\Administrator\workspace 立即下载

相关推荐

ThreadPool:java线程池的写法

线程池 java线程池的写法 这个类展示了在java中实现ThreadPool的一种方式! 您可以轻松阅读源文件,因为注释很详细。 尽情享受吧!

WhiteAgent:构建透明可调试AI智能体的开源框架实践

在人工智能工程化领域,智能体(Agent)作为连接大语言模型与实际应用的关键组件,其开发框架的设计直接影响着系统的可靠性与可维护性。传统智能体常因内部逻辑不透明、调试困难而被诟病为“黑盒”,这在高风险或复杂业务场景中尤为突出。为解决这一问题,透明性与可解释性成为智能体框架的核心设计原则,通过模块化架构、标准化的工具协议和完整的可观测性链路,使开发者能够清晰追踪智能体的决策过程、工具调用链与状态变迁。这种“白盒”设计不仅提升了系统的可调试性与可信度,更为智能体在自动化流程、个性化助手、企业服务集成等场景的规模

weixin_30546189的博客 424

Java 线程池框架

本文主要介绍了Java 线程池框架的相关知识。具有很好的参考价值,下面跟着小编一起来看下吧

Java多线程2--Runnable+静态代理实现线程

创建线程的另一种方法是声明实现 Runnable 接口的类。该类实现 run 方法。然后可以分配该类的实例,在创建 Thread 时作为一个参数来传递并启动 先创建一个Programmer类继承Runnable,重写Run方法 /* * 使用Runnable创建线程 * 1.类实现Runnable接口+重写run() --->真实角色类 * 2.启动多线程 使用静态代理 * ...

F的博客 769

Java线程池的拒绝策略实现详解

主要介绍了Java线程池的拒绝策略实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

JAVA线程池原理实例详解

主要介绍了JAVA线程池原理,结合实例形式详细分析了java线程池概念、原理、创建、使用方法及相关注意事项,需要的朋友可以参考下

java 进阶之路(书籍推荐)

学习Java,书籍是必不可少的学习工具之一,尤其是对于自学者而言。废话不多说,下边就给大家推荐一些Java进阶的好书。 第一部分:Java语言篇 1.《Java编程规范》 适合对象:初级、中级 介绍:这本书的作者是被誉为Java之父的James Gosling,入门者推荐阅读,对基础的讲解很不错。 2.《Java编程思想》 适合对象:初级、中级 介绍:豆瓣给出了9.1的评分,全球程序员广泛赞誉。有...

weixin_34221112的博客 717

Java线程池用法实战案例分析

主要介绍了Java线程池用法,结合具体案例形式分析了java线程池创建、使用、终止等相关操作技巧与使用注意事项,需要的朋友可以参考下

java线程池使用最全详解

线程池使用 前言 在执行一个异步任务或并发任务时,往往是通过直接new Thread()方法来创建新的线程,这样做弊端较多,更好的解决方案是合理地利用线程池,线程池的优势很明显,如下: 降低系统资源消耗,通过重用已存在的线程,降低线程创建和销毁造成的消耗; 提高系统响应速度,当有任务到达时,无需等待新线程的创建便能立即执行; 方便线程并发数的管控,线程若是无限制的创建,不仅会额外消耗大量系统资源,更是占用过多资源而阻塞系统或oom等状况,从而降低系统的稳定性。线程池能有效管控线程,统一分配、调优,提供资源

qq_40093255的博客 9万+

FlinkCDC数据同步Bug——同步性能由于写入并行度限制无法提升问题的解决

使用FlinkCDC进行数据同步时,出现增量阶段写入并行度强制为1导致整体同步性能无法提升问题的解决方案

csdn_lan的博客 2077

STM32F103C8T6实战:手把手教你搭建智能火灾报警系统(附MQ-2传感器调试技巧)

本文详细介绍了基于STM32F103C8T6单片机和MQ-2烟雾传感器的智能火灾报警系统搭建过程。从硬件选型、电路设计到软件开发,提供全面的实战指导,特别包含MQ-2传感器调试技巧,帮助开发者快速实现稳定可靠的智能火灾监控系统。

year5的博客 213

Java线程池参数详解

线程池是现代并发编程中不可或缺的工具,合理配置线程池参数能够显著提升应用的性能和稳定性。本文将深入剖析线程池的核心参数,包括核心线程数、最大线程数、线程存活时间、任务队列类型及拒绝策略等,结合实际案例帮助读者理解每个参数的作用及调优思路。

2301_80795057的博客 2万+

产品经理必备知识——API接口

在古代,我们的传输信息的方式有很多,比如写信、飞鸽传书,以及在战争中使用的烽烟,才有了著名的烽火戏诸侯,但这些方式传输信息的效率终究还是无法满足高速发展的社会需要。如果你选择允许,app就会根据你的当前位置为你提供更加个性化的一些服务,当然也有一些app拿到你的位置信息做出损害用户利益的行为,所以还是需要谨慎授权。首先,看接口文档的场景一般是自身业务模块需要获取外部的数据,但又不想自己重新开发,寻找外部已经实现的有开放能力的供应商(包含企业内部的)。通过发送请求和响应消息的方式实现程序间的通信。

WBKJ_Noah_的博客 3454

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万+

Mixly/Arduino实战:WS2812点阵动态显示自定义图案与汉字

本文手把手教你使用Mixly和Arduino驱动WS2812点阵屏,实现自定义图案与汉字的动态显示。内容涵盖硬件连接、取模软件设置、高效数据处理技巧(巧用Excel)、Mixly图形化编程及Arduino代码解析,并深入探讨动态显示与滚动汉字原理,最后提供常见问题排查与性能优化心得,助你从零开始轻松玩转智能硬件。

weixin_29185199的博客 454

NOAA气象数据下载攻略

各方搜寻气象数据下载途径,发现网上最多的就是从NOAA下载,但是中途有尝试过很多次都没有下载到,每次都是显示不可用,今天终于下载成功了,特此记录。 首先我是从这个网址进入的:National Centers for Environmental Information (NCEI) formerly known as National Climatic Data Center (NCDC) | NCEI offers access to the most significant archives of oc

lianqian66的博客 3万+

Java 线程池原理详解

本文全面解析Java线程池的实现原理和使用方法。线程池通过复用线程、控制并发数量、任务队列管理等机制提升系统性能。核心类是ThreadPoolExecutor,包含核心线程数、最大线程数、任务队列等关键参数配置。

微笑听雨 2086

NVIDIA Tao Toolkit环境配置踩坑

请搭配食用该文章为 Tao 安装中可能出现的问题进行解答,如果存在本文章中没出现的问题,欢迎提问,由我复现后更新文章。由于大部分云服务器厂商不能支持 docker,因此我使用的环境为2023年5月27日在平台租的 3080 旧版环境进行实验。

qq_36630208的博客 771

Java线程池详解

Java线程池详解

qq_24574189的博客 1442

基于STM32F1XX 、HAL库的LTR-303ALS-01 环境光传感器驱动应用C语言程序设计

printf("制造商ID: 0x%02X\r\n", LTR303_ReadManufacID());printf("器件ID: 0x%02X\r\n", LTR303_ReadPartID());LTR-303ALS-01是一款数字环境光传感器(ALS),由Lite-On公司生产。printf("LTR-303ALS初始化失败!printf("LTR-303ALS初始化成功!printf("数据无效\r\n");* @param mode: 0-待机, 1-激活。

PP_Cottage的博客 1032

汽车电子零部件(14):TMS热管理系统

TMS(thermal management system)热管理系统,这是新能源汽车诞生后随之而产生的一种新汽车零部件,一旦热管理失控会触发自燃,这种现象也是对EV来说是件头疼的事。汽车的热管理系统(TMS)是一个关键部件,有助于调节汽车电池组、车厢和其他车辆系统的温度。TMS的主要目的是在驾驶过程中保持最佳的电池性能和乘客舒适度。TMS使用各种加热和冷却系统来调节电池组和车厢的温度,并通过优化其使用,降低能耗,提高车辆的整体效率。

码农17年的博客 3160

详解java线程池

前言 java 常用有线程池

u010519674的专栏 385

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

java线程池详解

一,线程池的优点 1,降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。 2,提高响应速度。当任务到达时,任务可以不需要的等到线程创建就能立即执行。 3,提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。但是要做到合理的利用线程池,必须对其原理了如指掌。 ...

MrLee的博客 1270

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

java线程池详解及五种线程池方法详解

基础知识 Executors创建线程池 Java中创建线程池很简单,只需要调用Executors中相应的便捷方法即可,比如Executors.newFixedThreadPool(int nThreads),但是便捷不仅隐藏了复杂性,也为我们埋下了潜在的隐患(OOM,线程耗尽)。 Executors创建线程池便捷方法列表: 方法名 功能 newFixedThreadPool(int nThreads) 创建固定大小的线程池 newSingleThreadExecutor()

lixiangchibang的博客 3万+

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

上一篇: Spring Boot 集成 Memcached
下一篇: Mybatis的前世今生
刀哥谈Java
博客等级 码龄8年 110粉丝 84原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值