线程池

十二、连接池线程池配置——线程池 如果需要在 Spring Boot 中创建自定义线程池(例如用于特定的任务或服务),可以使用。 阅读详情

线程池

线程池

什么是线程池

Java中的线程池是运用场景最多的并发框架,几乎所有需要异步或并发执行任务的程序
都可以使用线程池。在开发过程中,合理地使用线程池能够带来3个好处。
第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
第二:提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
第三:提高线程的可管理性。线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,
还会降低系统的稳定性,使用线程池可以进行统一分配、调优和监控。但是,要做到合理利用
线程池,必须对其实现原理了如指掌。

线程池作用

线程池是为突然大量爆发的线程设计的,通过有限的几个固定线程为大量的操作服务,减少了创建和销毁线程所需的时间,从而提高效率。

如果一个线程的时间非常长,就没必要用线程池了(不是不能作长时间操作,而是不宜。),况且我们还不能控制线程池中线程的开始、挂起、和中止。

线程池的分类

ThreadPoolExecutor

Java是天生就支持并发的语言,支持并发意味着多线程,线程的频繁创建在高并发及大数据量是非常消耗资源的,因为java提供了线程池。在jdk1.5以前的版本中,线程池的使用是及其简陋的,但是在JDK1.5后,有了很大的改善。JDK1.5之后加入了java.util.concurrent包,java.util.concurrent包的加入给予开发人员开发并发程序以及解决并发问题很大的帮助。这篇文章主要介绍下并发包下的Executor接口,Executor接口虽然作为一个非常旧的接口(JDK1.5 2004年发布),但是很多程序员对于其中的一些原理还是不熟悉,因此写这篇文章来介绍下Executor接口,同时巩固下自己的知识。如果文章中有出现错误,欢迎大家指出。

Executor框架的最顶层实现是ThreadPoolExecutor类,Executors工厂类中提供的newScheduledThreadPool、newFixedThreadPool、newCachedThreadPool方法其实也只是ThreadPoolExecutor的构造函数参数不同而已。通过传入不同的参数,就可以构造出适用于不同应用场景下的线程池,那么它的底层原理是怎样实现的呢,这篇就来介绍下ThreadPoolExecutor线程池的运行过程。

 

corePoolSize: 核心池的大小。 当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中
maximumPoolSize: 线程池最大线程数,它表示在线程池中最多能创建多少个线程;
keepAliveTime: 表示线程没有任务执行时最多保持多久时间会终止。
unit: 参数keepAliveTime的时间单位,有7种取值,在TimeUnit类中有7种静态属性:

线程池四种创建方式

Java通过Executors(jdk1.5并发包)提供四种线程池,分别为:

newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。

newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。

newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。

newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

 

线程池:

降低资源消耗   提高效率 方便管理

降低资源消耗: 降低资源消耗 通过利用已经创建的线程降低线程创建和销毁造成的消耗(比如等待cpu去调度啊啥的 创建啊 调度啊 都需要消耗资源的)立即执行

run方法不一样而已,可以复用呀。run不一样 干的活不一样 

线程池溢出: 如果频繁创建多线程,非常占用cpu内存。比如 一直创建线程。。。 小伙伴你可以试试哈,搞卡了别找我哟哈哈   

使用线程池进行统一分配,调优和监控。

 

创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。示例代码如下:

注意Executors类 和Executor接口

package com.toov5.thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class ThreadPoolTest {
   
      
    public static void main(String[] args) {
        //可缓存的线程池
        ExecutorService cachedThreadPool =   Executors.newCachedThreadPool();
        for(int i =0; i<20;i++){
            final int temp = i;
            cachedThreadPool.execute(new Runnable() {
                public void run() {
                    System.out.println(Thread.currentThread().getName()+","+temp);
                }
            });    
        }
 }
}

看结果:

请看线程被复用了 

总结: 线程池为无限大,当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程。

源码:

这个构造函数  核心线程数 最大线程数

 这个线程池是可以无限大的~~

 

 

下一种线程池:newFixedThreadPool

创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。示例代码如下:

看下它的源码封装:

又是对于 ThreadPoolExecutor的封装

 核心线程数 最大线程数 传递过来比如3  那么就这3个来回复用 通过底层创建3个线程

 

package com.toov5.ThreadPoolTest;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class FixedThreadPoolTest {
   
      public static void main(String[] args) {
         //可固定长度的线程池,最多有3个,超出的放入队列
    ExecutorService fixedThreadPool =    Executors.newFixedThreadPool(3);
    for(int i=0;i<10;i++){
        final int temp = i;
        fixedThreadPool.execute(new Runnable() {
            public void run() {
              System.out.println(Thread.currentThread().getName()+","+temp);    
            }
        });
        
        
    }
    }
    
    
}
 

 

总结:因为线程池大小为3,每个任务输出index后sleep 2秒,所以每两秒打印3个数字。

定长线程池的大小最好根据系统资源进行设置。如Runtime.getRuntime().availableProcessors()

 

 

newScheduleThreadPool:

创建一个定长线程池,支持定时及周期性任务执行。延迟执行示例代码如下:

package com.toov5.ThreadPoolTest;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

public class ScheduledThreadPoolTest {
  
      public static void main(String[] args) {
    ScheduledExecutorService scheduledExecutorService=Executors.newScheduledThreadPool(3);
          for(int i=0;i<20;i++){
              final int temp = i;
              scheduledExecutorService.execute(new Runnable() {
                public void run() {
                    System.out.println(Thread.currentThread().getName()+","+temp);
                }
            });
          }
    }
    
}

 运行结果:

这个是不可以进行定时的任务调度的,看这段代码:

package com.toov5.ThreadPoolTest;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ScheduledThreadPoolTest {
  
      public static void main(String[] args) {
    ScheduledExecutorService scheduledExecutorService=Executors.newScheduledThreadPool(3);    
      for(int i=0;i<20;i++){
          final int temp = i;
          scheduledExecutorService.schedule(new Runnable() {
            public void run() {
                System.out.println(Thread.currentThread().getName()+","+temp);
            }
        } , 3, TimeUnit.SECONDS);  //三秒钟之后执行任务调度
      }
    
    
    }
    
}

 三秒之后出结果:

 

单化线程的线程池:

创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。示例代码如下:

package com.toov5.ThreadPoolTest;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class SingleThreadExecutor {
     public static void main(String[] args) {
         //单化线程
     ExecutorService singleThreadExecutor  = Executors.newSingleThreadExecutor();    
     for(int i=0;i<10;i++){
         final int temp =i;
         singleThreadExecutor.execute(new Runnable() {
            public void run() {
                System.out.println(Thread.currentThread().getName()+","+temp);
            }
        });
         
     }
       
    singleThreadExecutor.shutdown(); //停止线程池

    }
}

 

 

 都是第一个线程,而且代码从上往下执行:

看源码:

传入的1 1 

 

怎么根据线程池告警修改线程池参数 调参通知、队列容量告警、拒绝策略告警必然是需要的 核心微服务: 必须加上 调参通知、队列容量告警、拒绝策略告警 如果是对于设备时效性要求较高=>加上 任务排队超时告警、任务执行超时告警 如果是长任务=>加上 任务执行超时告警、线程池活跃度告警。(线程池告警)该线程池的任务队列告警阈值需要降低阈值优化,如果是核心业务,则需要减少降低限度(如5%),直至可以在运维发现问题后,有足够时间让开发排查;可有可无的微服务,要避免浪费资源,也需要线程池监控查看配置,此时线程池情况可以做一个较好的缩容的指标。 阅读详情

相关推荐

深入线程池

像是服务员和厨师,要是都做请两个人把这两个任务一起做了,等同时来两个客人的时候,两人同时去服务客人,这时就没人做饭了,就是卡死在这一步,这就是一种饥饿。(ForkJoinP,它体现的是一种分治思想,适用于能够进行任务拆分的cpu密集型运算(Fork/Join默认创建cpu核心数相同的线程池。Fork/Join在分治的基础上加入了多线程,可以把每个任务的分解和合并交给不同的线程来完成,进一步提升了运算效率。整个线程池表现为线程数会根据任务量不断增长,没有上限,当任务执行完毕,空闲1min后释放线程。

2302_80742310的博客 1027

让bug无所遁形!你真的会Java 线上问题排查思路、正确使用常用工具?

本文总结了一些常见的线上应急现象和对应排查步骤和工具。分享的主要目的是想让对线上问题接触少的同学有个预先认知,免得在遇到实际问题时手忙脚乱。 只不过这里先提示一下。在线上应急过程中要记住,只有一个总体目标:尽快恢复服务,消除影响。不管处于应急的哪个阶段,我们首先必须想到的是恢复问题,恢复问题不一定能够定位问题,也不一定有完美的解决方案,也许是通过经验判断,也许是预设开关等,但都可能让我们达到快速恢复的目的,然后保留部分现场,再去定位问题、解决问题和复盘。 在大多数情况下,我们都是先优先恢复服务,保留下当

weixin_49723683的博客 789

线程池详解:线程池七大核心参数、线程池工作原理、线程池的创建方式、线程池的拒绝策略、如何合理分配线程池大小

线程池是一种用于管理和复用线程的机制,它允许我们在需要执行一些并发任务时,可以重复使用已经创建好的线程,而不是每次都创建新的线程。这样可以减少线程创建和销毁的开销,提高系统的性能和响应速度。并发线程池的优点包括: 提高系统的性能和吞吐量,因为可以重复使用已经创建好的线程,减少线程创建和销毁的开销。 可以控制并发任务的执行顺序和数量,从而避免系统资源被过度占用。 可以设置线程池的参数,如核心线程数、最大线程数、任务队列等,以满足不同场景的需求。

小小鱼儿小小林的博客 1万+

什么是线程池,线程池的概念、优点、缺点,如何使用线程池,最大线程池怎么定义?

线程池的优点包括重用线程、控制并发度、提供线程管理和监控等。通过适当地配置线程池的大小和任务队列的容量,可以充分利用系统资源,提高程序的性能和响应速度。同时,线程池可以避免线程创建和销毁的开销,减少了资源的浪费。线程池的基本概念是,在应用程序启动时创建一定数量的线程,并将它们保存在线程池中。当需要执行任务时,从线程池中获取一个空闲的线程,将任务分配给该线程执行。线程池的设计思想是为了避免频繁地创建和销毁线程的开销,以及控制并发执行的线程数量,从而提高系统的性能和资源利用率。

mcband的博客 4万+

用Java和MQTT搞定大疆无人机自动巡检:一个真实机场项目的踩坑与优化记录

本文详细介绍了如何利用Java和MQTT协议实现大疆无人机在机场自动巡检系统的开发与优化。通过实战案例分享系统架构设计、通信协议选型、断线重连机制及数据通道优化等关键环节,帮助开发者解决GPS信号漂移、MQTT消息风暴等典型问题,提升系统性能和可靠性。

weixin_30275415的博客 495

如何在Vitis 2023.1上快速搭建LWIP Echo Server(附YT8521S PHY调试心得)

本文详细介绍了在Vitis 2023.1开发环境下,基于Xilinx MPSoC平台快速搭建LWIP Echo Server的完整实战流程。内容涵盖从Vivado硬件工程配置、Vitis软件工程创建,到关键代码剖析与定制化修改,并重点分享了调试非标准PHY芯片(如YT8521S)的宝贵心得与常见问题排查方法,旨在帮助开发者高效实现FPGA与上位机间的可靠网络通信验证。

weixin_29250403的博客 136

35.Java线程池(线程池概述、线程池的架构、线程池的种类与创建、线程池的底层原理、线程池的工作流程、线程池的拒绝策略、自定义线程池)

35.Java线程池(线程池概述、线程池的架构、线程池的种类与创建、线程池的底层原理、线程池的工作流程、线程池的拒绝策略、自定义线程池)

weixin_52173250的博客 1762

Agent测试框架Harbor指南

Harbor是一个AI Agent单元测试框架,用于自动化测试AI代理在容器环境中的任务执行能力。它支持18+种AI代理,通过沙箱隔离和自动验证机制评估任务完成情况。任务必须具有可编程验证的输出结果,适合代码、数据、系统等可量化任务,不适合创意写作等主观任务。Harbor采用CLI操作方式,核心架构包含Job管理、Trial执行和验证器三个层级,执行流程包括环境启动、Agent执行和结果验证。任务目录包含指令文件、配置文件、Docker环境定义和测试脚本等必需组件,通过测试脚本自动判断任务完成质量。

loo_Charles_ool的博客 1404

线程池怎么调优?线程池的几种方式?及线程池的实战

线程池的调优

weixin_60153382的博客 2701

【脑电分析系列】第15篇:脑电功能连接性与脑网络分析(二):Granger因果性、图论指标与复杂网络构建

摘要: 本文深入探讨了脑电(EEG)分析中的高阶连接性方法——有效连接(Effective Connectivity),重点介绍了Granger因果性(Granger Causality, GC)的原理与应用。GC通过统计预测揭示脑区间信息流动方向,超越了传统功能连接的同步性分析。文章还结合图论指标(如度、路径长度、聚类系数和模块化)量化脑网络的拓扑结构,并通过Python代码(MNE和NetworkX库)演示了从EEG数据构建、分析复杂脑网络的完整流程。该研究为理解大脑动态互动、认知任务信息流及神经系统疾

qq_32516809的博客 1563

微信DAT图片恢复全攻略:从文件定位到批量解密(附最新路径变化)

本文提供了一份详尽的微信DAT图片恢复指南,涵盖新旧版本文件路径变化解析、DAT文件定位方法以及批量解密操作步骤。针对微信图片加密存储为DAT格式的痛点,文章介绍了高效易用的图形化解密工具,帮助用户将加密文件快速还原为JPG、PNG等可查看格式,并强调了数据安全与隐私保护的重要性。

p4q5r6s7t的博客 744

线程池——线程池

本文主要讲线程池:1)线程池的引入;2)Java标准库中的线程池;3)ThreadPoolExecutor 构造方法和拒绝策略;4)实现一个简单的线程池

2301_76937176的博客 1167

计算机组成原理实验:手把手教你用模拟程序实现中断机制(附完整代码)

本文通过一个计算机组成原理模拟实验,手把手教你从零实现一个可工作的中断系统。实验详细演示了如何配置中断控制器、编写主程序与中断服务程序,并观察中断响应、现场保护和恢复的全过程,深入解析了中断原理的核心机制。

471

spring 的线程池还是 java 的线程池

Java 提供了一个强大的并发库,其中包含了线程池的基本实现。线程池是接口的实现类,用于管理线程的创建、执行和终止。通过线程池,开发者可以避免频繁创建和销毁线程带来的开销,从而提升应用程序的性能。Spring 框架对 Java 的并发库进行了封装,使得线程池的配置更加简洁和灵活。Spring 提供了接口,这是对 JavaExecutor接口的扩展,允许开发者更容易地配置和管理线程池。Spring 的线程池配置通常通过 XML 或 Java 配置类来实现,并且 Spring 提供了多种实现,如等。

Flying_Fish_roe的博客 1674

Unreal 从入门到进阶 之 如何实现Pixel Streaming

Unreal Engine 5 (UE5) 的 Pixel Streaming 是一项基于云端的实时流媒体技术,允许将 UE5 应用的高质量图形渲染结果通过 WebRTC 协议传输到用户的浏览器或轻量级设备,同时将用户输入(如鼠标、键盘、触控)回传到服务器处理。UE的插件相对比较好用,但是就是环境下载总是失败。希望这篇文章对你有所帮助。

TxNet 1369

《Python入门到精通》函数详解

函数就是一段「封装」起来的「代码」,目的是提高代码的「模块性」和「复用性」。 2、函数的参数 2.1、变量的就近原则 2.2、传递参数 2.3、形参和实参 2.4、位置参数 2.5、缺省参数 2.6、可变类型和不可变类型 2.7、关键字参数 3、匿名函数 4、函数的返回值

wangyuxiang946的博客 1万+

Tomcat线程池监控及线程池原理分析

当有新任务时,Tomcat的线程池核心线程如果已经创建完了,Tomcat会尽最大努力开启新的非核心线程去执行新任务,而JUC的ThreadPoolExecutor则是入队,等待队列满了再创建新的非核心线程去执行任务。

wenyixicodedog的博客 1万+

VC中sqlite的使用

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

线程池讲解

/核心线程池大小//最大线程数//队列容量//活跃时间//线程名字前缀使用}, iAlgoFilter.getType() + "-----计算").start();}*/@Overridelog.info("当前线程:{},执行特征编号:{}的:{} 计算", Thread.currentThread().getName(),code, iAlgoFilter.getType());});

cf的博客 1664

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

线程池、及Springboot线程池实践

线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。

jainszhang的博客 1722

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

线程池详解,生命周期,线程池种类,预热

线程池详解,生命周期,线程池种类,预热

hello world 1315

【线程池】Tomcat线程池

最近看到篇关于 Tomcat 线程池的博客,因为之前只看过 JDK 线程池,记录一下。在微服务横行的今天,确实还是有必要研究研究 Tomcat 的线程池Tomcat 线程池和 JDK 线程池最大的不同就是它先把最大线程数用完,然后再提交任务到队列里面。深入理解线程池(ThreadPoolExecutor)——细致入微的讲源码。workerstarted = true-优快云博客本文主要介绍了 Tomcat 线程池的运行流程,和 JDK 线程池的流程比起来,它确实不一样。

m0_64944491的博客 1724

Java线程池原理及四种线程池的使用

Java通过Executors提供四种线程池,分别为: newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。 newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。 newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执

honghailiang的专栏 1万+

Java 线程池

在实际使用中,线程是很占用系统资源的,如果对线程管理不善很容易导致系统问题。(1)线程池中最多执行1个线程,之后提交的线程活动将会排在队列中依次执行。(1)线程池中最多执行1个线程,之后提交的线程活动将会排在队列中依次执行。(2)线程池中的线程可进行缓存重复利用和回收。(1)线程池中的线程处于一定的量,可以很好的控制线程的并发量。(2)线程可以重复被使用,在显式关闭之前,都将一直存在。(1)线程池中具有指定数量的线程,即便是空线程也将保留。(3)当线程池中,没有可用线程,会重新创建一个线程。

ggfgfggg的博客 1065

线程池总结

线程数的设置主要取决于业务是属于 IO 密集型还是 CPU 密集型。对于 CPU 密集型任务,其主要工作是进行大量的计算,且较少出现导致线程阻塞的情况。在这种场景下,一般将线程数设置为 CPU 核心数 + 1。例如,如果服务器拥有 8 个 CPU 核心,那么适宜将线程数设定为 9。如此一来,能够充分利用 CPU 资源,同时避免因过多线程切换而产生的额外开销。对于 IO 密集型任务,执行过程中需要大量的 I/O 操作,如磁盘 I/O、网络 I/O 等,这可能导致大量的线程阻塞。

Brenda_Bestow的博客 1151

JUC线程池和spring线程池

简介:目前常用的线程池有两种,一种是jdk自带的ThreadPoolExecutor来创建线程池,另一种是spring框架中的ThreadPoolTaskExecutor来创建线程池。 JDK自带的线程池 (1)线程池执行过程入下图: (2)常用的线程池 使用Executors创建线程池:这是jdk自带的创建线程池的方法。通过Exceutors创建线程池,常见的线程池有四种: Executors.newFixedThreadPool(int nThreads):固定长度的线程池...

qq_27661881的博客 1802
上一篇: 使用并发队列实现生产者与消费者
下一篇: 线程池原理剖析
Art&Code
博客等级 码龄7年 77粉丝 554原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值