【JUC并发编程】线程池底层原理(创建方式/ 核心参数/ SpringBoot整合/ 五种状态)

AURIX™ TC3xx 调试口保护 secure debug AURIX™ TC3xx 调试口保护 secure debug UCB_DBG_ORIG and UCB_DBG_COPY Content 使用Debug Password 保护调试接口设置 项目硬件接口保护方案 hexview Lock using UDE Unlockusing UDE Lock using Lauterbach Unlock using Lauterbach 阅读详情


1. 什么是线程池

线程池和数据库连接池非常类似,可以统一管理和维护线程,减少没有必要的开销。

2. 为什么要使用线程池

因为频繁的开启线程或者停止线程,线程需要从新被 cpu 从就绪到运行状态调度,需要发生 cpu 的上下文切换,效率非常低。
在这里插入图片描述
在这里插入图片描述

3. 哪些地方会使用到线程池

实际开发项目中 禁止自己 new 线程。必须使用线程池来维护和创建线程。
项目使用多线程异步发送短信----多线程

4. 线程池有哪些作用

1.降低资源消耗:通过池化技术重复利用已创建的线程,降低线程创建和销毁造成的损耗。
2.提高响应速度:任务到达时,无需等待线程创建即可立即执行。
3.提高线程的可管理性:线程是稀缺资源,如果无限制创建,不仅会消耗系统资源,还会因
为线程的不合理分布导致资源调度失衡,降低系统的稳定性。使用线程池可以进行统一的分
配、调优和监控。
4.提供更多更强大就允许任务延期执行或定期执行。

5. 线程池的创建方式

Executors.newCachedThreadPool(); 可缓存线程池
Executors.newFixedThreadPool();可定长度 限制最大线程数
Executors.newScheduledThreadPool() ; 可定时
Executors.newSingleThreadExecutor(); 单例
真实底层都是基于 ThreadPoolExecutor 构造函数封装 线程池

6. 线程池底层是如何实现复用的

在这里插入图片描述
核心复用机制:最多只会创建2个线程 提交10个线程任务 涉及到缓存

  1. 定一个容器(LinkedBlockingQueue)缓存提交的线程任务
  2. 提前创建好固定数量的线程一直在运行状态(5个线程)
  3. 无界(无限存储元素) 有界(有限制容量存储元素)
  4. 提交线程任务会存放在LinkedBlockingQueue中缓存起来
  5. 一直在运行的线程就会从LinkedBlockingQueue取出线程任务执行。
  6. 如果提交线程任务到LinkedBlockingQueue中存放,如果阻塞队列满了
    如何处理—走拒绝策略。

线程池缺陷:线程一直在运行状态---可能会消耗到cpu的资源

线程池底层实现原理?
本质思想:创建一个线程,不会立马停止或者销毁而是一直实现复用。

  1. 提前创建固定大小的线程一直保持在正在运行状态;(可能会非常消耗 cpu 的资源)
  2. 当需要线程执行任务,将该任务提交缓存在并发队列中;如果缓存队列满了,则会执行 拒绝策略;
  3. 正在运行的线程从并发队列中获取任务执行从而实现多线程复用问题;

线程池核心点:复用机制

  1. 提前创建好固定的线程一直在运行状态----死循环实现
  2. 提交的线程任务缓存到一个并发队列集合中,交给我们正在运行的线程执行
  3. 正在运行的线程就从队列中获取该任务执行

简单模拟手写 Java 线程池:

public class DemoExecutor {
    private LinkedBlockingDeque<Runnable> linkedBlockingDeque;
    private static volatile boolean isRun = true;

    /**
     * dequeSize队列容量大小
     * threadCount 初始化一直正在运行的线程数
     *
     * @param dequeSize
     * @param threadCount
     */
    public DemoExecutor(int dequeSize, int threadCount) {
        linkedBlockingDeque = new LinkedBlockingDeque<Runnable>(dequeSize);
        for (int i = 0; i < threadCount; i++) {
            TaskThread taskThread = new TaskThread();
            taskThread.start();
        }
    }

    public void execute(Runnable runnable) {
        linkedBlockingDeque.offer(runnable);
    }

    class TaskThread extends Thread {
        @Override
        public void run() {
            while (isRun || linkedBlockingDeque.size() > 0) {
                Runnable runnable = linkedBlockingDeque.poll();
                if (runnable != null) {
                    runnable.run();
                }

            }
        }
    }

    public static void main(String[] args) {
        DemoExecutor demoExecutor = new DemoExecutor(20, 2);
        for (int i = 0; i < 10; i++) {
            int finalI = i;
            demoExecutor.execute(() -> {
                System.out.println(Thread.currentThread().getName() + ",i:" + finalI);
            });
        }
        demoExecutor.isRun = false;
    }

}


7. ThreadPoolExecutor核心参数

corePoolSize:核心线程数量 一直正在保持运行的线程 2
maximumPoolSize:最大线程数,线程池允许创建的最大线程数。满足最大线程数>=核心线程数
核心线程数量是为2 一直在运行状态 最大线程数是4 是当我们队列容量满了 就触发创建线程 最大线程数(4)-核心线程数量(2) 额外在创建2个线程来帮忙

keepAliveTime:超出corePoolSize后创建的线程的存活时间。 60s
unit:keepAliveTime的时间单位。

workQueue:任务队列,用于保存待执行的任务。—缓存提交的任务
threadFactory:线程池内部创建线程所用的工厂。–线程池内部工厂 自定义线程池
handler:任务无法执行时的处理器。—当我们队列满了,走其他处理策略

核心原理:
提交任务的时候比较核心线程数,如果当前任务数量小于核心线程数的情况下,则直接复用线程执行。
如果任务量大于核心线程数,则缓存到队列中。
如果缓存队列满了,且任务数小于最大线程数的情况下,则创建线程执行。
如果队列且最大线程数都满的情况下,则走拒绝策略。
注意:最大线程数,在一定时间没有执行任务 则销毁避免浪费cpu内存。

专业术语。
1.当线程数小于核心线程数时,创建线程。
2.当线程数大于等于核心线程数,且任务队列未满时,将任务放入任务队列。
3.当线程数大于等于核心线程数,且任务队列已满
3.1若线程数小于最大线程数,创建线程
3.2若线程数等于最大线程数,抛出异常,拒绝任务

8. 如何自定义线程池

public class MyThreadPoolExecutor {
    public static ExecutorService newFixedThreadPool(int corePoolSize, int maximumPoolSize, int blockingQueue) {
        return new ThreadPoolExecutor(corePoolSize, maximumPoolSize,
                60L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>(blockingQueue), new DemoExecutionHandler());
    }
}

9. 为什么阿里巴巴java开发手册中不推荐使用jdk自带线程池

因为默认的 Executors 线程池底层是基于 ThreadPoolExecutor 构造函数封装的,采用无界队列存放缓存任务,会无限缓存任务容易发生 内存溢出,会导致我们最大线程数会失效。
在这里插入图片描述

10. 线程池队列满了拒绝策略

如果队列满了,且任务总数>最大线程数则当前线程走拒绝策略。
可以自定义异拒绝异常

rejectedExecutionHandler:任务拒绝处理器
两种情况会拒绝处理任务
1.当线程数已经达到maxPoolSize,切队列已满,会拒绝新任务
2.当线程池被调用shutdown()后,会等待线程池里的任务执行完毕,再shutdown。如果在调用shutdown()和线程池真正shutdown之间提交任务,会拒绝新任务。
线程池会调用rejectedExecutionHandler来处理这个任务。如果没有设置,默认是AbortPolicy,会抛出异常。

ThreadPoolExecutor类有几个内部实现类来处理拒绝任务
1.AbortPolicy 丢弃任务,抛运行时异常
2.CallerRunsPolicy 执行任务
3.DiscardPolicy 忽视,什么都不会发生
4.DiscardOldestPolicy 从队列中踢出最先进入队列(最后一个执行)的任务
5.实现RejectedExecutionHandler接口,可自定义处理器

队列满的话 可以将任务记录到本地磁盘或者网络中保存,后期可以直接使用人工补偿的形式。

public static ExecutorService newFixedThreadPool(int corePoolSize, int maximumPoolSize) {
    linkedBlockingQueuel = new LinkedBlockingQueue<Runnable>(2);
    return new ThreadPoolExecutor(corePoolSize, maximumPoolSize,
            0L, TimeUnit.MILLISECONDS,
            linkedBlockingQueuel, new MyRejectedExecutionHandler());
}

11. 核心线程数?一直在运行状态如何避免cpu飙高问题

底层采用 runnables.poll(3, TimeUnit.SECONDS);

线程池中 核心线程 在运行中从队列中取出任务 如果队列中是为空的话,则当前
线程会阻塞,主动的释放cpu执行权。
如果有另外的线程提交向线程池中提交新的任务,则当前(核心线程会被)
主动唤醒起来 ,从队列中取出该任务执行。
在这里插入图片描述

12. 自定义线程池名称

自定义线程池的名称(ThreadPoolExecutor)
目的:有时候为了快速定位出现错误的位置,在采用线程池时我们需要自定义线程池的名称。
创建ThreadFactory(ThreadPoolExecutor默认采用的是DefaultThreadFactory,可以参照代码)

public class DemoNamedThreadFactory implements ThreadFactory {
    private static final AtomicInteger poolNumber = new AtomicInteger(1);
    private final ThreadGroup group;
    private final AtomicInteger threadNumber = new AtomicInteger(1);
    private final String namePrefix;

   DemoNamedThreadFactory() {
        SecurityManager s = System.getSecurityManager();
        group = (s != null) ? s.getThreadGroup() :
                Thread.currentThread().getThreadGroup();
        namePrefix = "demo" +
                poolNumber.getAndIncrement() +
                "-thread-";
    }

    public Thread newThread(Runnable r) {
        Thread t = new Thread(group, r,
                namePrefix + threadNumber.getAndIncrement(),
                0);
        if (t.isDaemon())
            t.setDaemon(false);
        if (t.getPriority() != Thread.NORM_PRIORITY)
            t.setPriority(Thread.NORM_PRIORITY);
        return t;
    }
}


13. 线程池参数如何配置

  1. corePoolSize(核心线程数)
  2. queueCapacity(任务队列容量)
  3. maxPoolSize(最大线程数)
  4. keepAliveTime(线程空闲时间)
  5. allowCoreThreadTimeout(允许核心线程超时)
  6. rejectedExecutionHandler(任务拒绝处理器)

13.1 CPU密集型与IO密集型区别

核心线程数配置多少比较合理呢?

IO密集型—linux内核 用户态到内核态切换过程

Cpu密集型:当前线程做大量的程序计算;
1.CPU密集型也叫计算密集型,指的是系统的硬盘、内存性能相对CPU要好很多,此时,系统运作大部分的状况是CPU Loading 100%,CPU要读/写I/O(硬盘/内存),I/O在很短的时间就可以完成,而CPU还有许多运算要处理,CPU Loading很高。
2.在多重程序系统中,大部份时间用来做计算、逻辑判断等CPU动作的程序称之CPU bound。例如一个计算圆周率至小数点一千位以下的程序,在执行的过程当中绝大部份时间用在三角函数和开根号的计算,便是属于CPU bound的程序。
3.CPU bound的程序一般而言CPU占用率相当高。这可能是因为任务本身不太需要访问I/O设备,也可能是因为程序是多线程实现因此屏蔽掉了等待I/O的时间。
4. cpu 密集型(CPU-bound)线程池设计 最佳线程数=cpu核数或者cpu核数±1

核心数-----====cpu的核数16核

IO密集型:比如 当前线程读文件、写文件、传输文件、网络请求属于密集型;
IO密集型指的是系统的CPU性能相对硬盘、内存要好很多,此时,系统运作,大部分的状况是CPU在等I/O (硬盘/内存) 的读/写操作,此时CPU Loading并不高。
I/O bound的程序一般在达到性能极限时,CPU占用率仍然较低。这可能是因为任务本身需要大量I/O操作,而pipeline做得不是很好,没有充分利用处理器能力。比如接收一个前端请求–解析参数–查询数据库–返回给前端这样的,那么就是IO密集型的,例如web应用。

I/O密集型(I/O-bound)线程池设计
最佳线程数目 = ((线程等待时间+线程CPU时间)/线程CPU时间 )* CPU数目

线程等待时间所占比例越高,需要越多线程。线程CPU时间所占比例越高,需要越少线程

假如一个程序平均每个线程CPU运行时间为0.5s,而线程等待时间(非CPU运行时间,比如IO)为1.5s,CPU核心数为16,那么最佳的线程数应该是? 核心线程数==64
Int j =1;
Int z=2;
// rpc请求 1.5s

根据上面这个公式估算得到最佳的线程数:((0.5+1.5)/0.5)*16=64。

代码cpu密集型 阻塞时间比较少

13.2 SpringBoot项目中如何整合线程池

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.ThreadPoolExecutor;

@Configuration
public class DemoThreadPoolConfig {

    /**
     * 线程核心数
     */
    @Value("${demo.thread.corePoolSize}")
    private int corePoolSize;
    /**
     * 线程最大数
     */
    @Value("${demo.thread.maxPoolSize}")
    private int maxPoolSize;
    /**
     * 任务容量
     */
    @Value("${demo.thread.queueCapacity}")
    private int queueCapacity;
    /**
     * 允许空闲时间,默认60
     */
    @Value("${demo.thread.keepAlive}")
    private int keepAlive;

    @Bean
    public TaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.setCorePoolSize(corePoolSize);
        threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);
        threadPoolTaskExecutor.setQueueCapacity(queueCapacity);
        threadPoolTaskExecutor.setKeepAliveSeconds(keepAlive);
        threadPoolTaskExecutor.setThreadNamePrefix("demoThread-");
        //设置拒绝策略 当线程数达到最大时,如何处理新任务
        //CallerRunsPolicy 不由线程池中线程执行,由调用者所在线程执行
        threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        threadPoolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        return threadPoolTaskExecutor;
    }
}


14. 线程池五种状态

线程池的5种状态:Running、ShutDown、Stop、Tidying、Terminated
在这里插入图片描述
线程池内部的5种状态

1.RUNNING
状态说明:线程池处在RUNNING状态时,能够接收新任务,以及对已添加的任务进行处理。
状态切换:线程池的初始化状态是RUNNING。换句话说,线程池被一旦被创建,就处于RUNNING状态,并且线程池中的任务数为0!

2.SHUTDOWN
状态说明:线程池处在SHUTDOWN状态时,不接收新任务,但能处理已添加的任务。
状态切换:调用线程池的shutdown()接口时,线程池由RUNNING -> SHUTDOWN。

3.stop
状态说明:线程池处在STOP状态时,不接收新任务,不处理已添加的任务,并且会中断正在处理的任务。
状态切换:调用线程池的shutdownNow()接口时,线程池由(RUNNING or SHUTDOWN ) -> STOP。

4.TIDYING
状态说明:当所有的任务已终止,ctl记录的”任务数量”为0,线程池会变为TIDYING状态。当线程池变为TIDYING状态时,会执行钩子函数terminated()。terminated()在ThreadPoolExecutor类中是空的,若用户想在线程池变为TIDYING时,进行相应的处理;可以通过重载terminated()函数来实现。
状态切换:当线程池在SHUTDOWN状态下,阻塞队列为空并且线程池中执行的任务也为空时,就会由 SHUTDOWN -> TIDYING。
当线程池在STOP状态下,线程池中执行的任务为空时,就会由STOP -> TIDYING。

5.TERMINATED
状态说明:线程池彻底终止,就变成TERMINATED状态。
状态切换:线程池处在TIDYING状态时,执行完terminated()之后,就会由 TIDYING -> TERMINATED。

《缠中说禅108课》5:市场无须分析,只要看 喜欢吹牛皮的,在市场里最常见,例如一种以分析市场、吹牛皮为生的职业,叫什么股评、专家的。此类人不过是市场上的寄生虫,真正的猎手只会观察、操作,用嘴是打不了豺狼的。 市场就是一个狩猎场,首先你要成为一个好猎手,而一个猎手,首先要习惯于无言。如果真有什么真理,那真理也是无言的。可言说的,都不过是人类思想的分泌物,臭气熏天。真不可言说了,就无不可言,言而无言,是乃真言。 一个好的猎手,可以没有嘴巴,但一定会有一双不为外物所动的眼睛,在这眼睛下,一切如幻化般透明。要不被外物所动,则首先要不被自我所迷惑,其实.. 阅读详情

相关推荐

关于42步进电机驱动——基于STM32 HAL库实现

我找了好多资料,好多关于42步进电机的都是文档,这么文档都需要积分,需要积分就算了内容还非常差,浪费时间电脑的内存。关于大部分是基于Arduino51去驱动的 42步进电机驱动硬件如下: 首先你要了解步进电机的驱动原理,我也不啰嗦了,请看这边博客: 二相四线,四相五线,四相六线步进电机接线及驱动方法 , 看完这篇你就知道驱动接线的原理了。 起初我也为如何接线烦恼,因为有些博客在讲述这些问题的时候没有讲的很透彻。 方法如下: ①用万用表调到欧姆档,用其中一个表笔搭在一个引脚上,依次测其它.

Jodan132的博客 1万+

结合JUCSpringboot优雅停机

具体看下SmartLifecycle这个方法,我们发现,是一个callback函数,只有当stop完成后,再会执行我们设置的函数,也就是latch.countDown()代码可能有点多,既然坚持到这里了,还是把调用栈详细写出来。doShutdown(callback) 关键。

m0_71777195的博客 228

万字长文:YOLOv5+RK3588 NPU多线程加速全攻略——从理论到部署的终极优化

RK3588 NPU多线程加速优化教程摘要 本教程深入讲解了如何利用线程池技术优化RK3588 NPU上的YOLO目标检测模型推理性能。RK3588内置3个NPU核心,理论算力达6TOPS,为多线程优化提供了硬件基础。教程详细解析了线程池核心组件(任务队列、工作线程、同步机制)实现架构,包括类设计、初始化流程、工作线程逻辑(任务获取、NPU推理、结果存储三个阶段)以及任务提交/获取机制。通过预分配模型实例、线程绑定、流量控制等优化手段,实现了从单线程28FPS到多线程120FPS的显著性能提升,为边缘A

LXY_LOVE36的博客 1070

Juc05_线程池概述、创建方式、七大参数底层工作原理、拒绝策略

Juc05_线程池概述、创建方式、七大参数底层工作原理、拒绝策略

所得皆惊喜 5909

SpringBoot_JUC工具使用

文章目录前言Semaphore[信号量]示例--控制耗时任务执行的线程数CountDownLatch[倒计时器]示例--并发加载缓存 前言 记录springboot项目环境下JUC工具的使用场景 Semaphore[信号量] 信号量,用来限制能同时访问共享资源的线程上限 示例–控制耗时任务执行的线程数 /** * 控制耗时任务执行的线程数 */ @Api(tags = "Semaphore测试") @RestController @RequestMapping("/semaphore/test")

Myron_007的博客 954

JUC——线程池的7大参数4种拒绝策略

线程池的优势 1.线程复用,减少线程创建、销毁的开销,提高性能 2.提高响应速度,当任务到达时,无需等待线程创建就能立即执行。 3.提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资 源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优监控。 线程池七大参数 1.corePoolSize核心线程数。 当提交一个任务时,线程池创建一个新线程执行任务,此时线程不会复用。如果当前线程数为corePoolSi...

qq_57205114的博客 1516

springboot之多任务并行+线程池处理

最近项目中做到一个关于批量发短信的业务,如果用户量特别大的话,不能使用单线程去发短信,只能尝试着使用多任务来完成!我们的项目使用到了方式二,即Future的方案 Java 线程池 Java通过Executors提供四种线程池,分别为: newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。 ...

MiChong的博客 6万+

JUC并发编程系列】深入理解Java并发机制:高效并发背后的守护者(八、线程池的秘密)

本文深入浅出地介绍了线程池的基本概念及其在Java中的实现方式,探讨了为什么使用线程池及其应用场景。通过对ThreadPoolExecutor构造函数参数的剖析,揭示了线程池内部的工作机制,包括线程复用、拒绝策略及线程池的不同状态。最后,提供了在不同计算负载下线程池参数的最佳实践配置建议,并简述了如何在Spring Boot项目中整合自定义线程池,以提升应用的并发性能稳定性。

欢迎来到我的技术空间!我是一名经验丰富的Java开发工程师,热衷于分享我在软件开发领域的知识和心得。在这个博客里,您会发现一系列关于Java编程的文章,包括最佳实践、技术趋势、代码优化技巧以及一些有趣的项目案例。无论是初学者还是有经验的开发者,都能在这里找 2059

美团动态线程池,香啊!

基于以上背景分析,我们对线程池 ThreadPoolExecutor 做一些扩展增强,主要实现以下目标」❝1.实现对运行中线程池参数的动态修改,实时生效2.实时监控线程池的运行状态,触发设置的报警策略时报警,报警信息推送办公平台3.定时采集线程池指标数据,配合像 grafana 这种可视化监控平台做大盘监控❞「经过多个版本的迭代,目前最新版本 v1.0.9 具有以下特性」✅「代码零侵入」:所有配置都放在配置中心,对业务代码零侵入「轻量简单」:基于 SpringBoot 实现,引入starter。

IT_1024的博客 709

美团动态线程池,真香啊!

现在大多数的互联网项目其实都会微服务化部署,有一套自己的服务治理体系,微服务组件中的分布式配置中心扮演的就是动态修改配置, 实时生效的角色。:提供多种报警维度(配置变更通知、活性报警、容量阈值报警、拒绝触发报警、任务执行或等待超时报警),已支持企业微信、钉钉、飞书、邮件报警,同时提供 SPI 接口可自定义扩展实现。答案是肯定的,而且配置中心相对都是高可用的, 使用它也不用过于担心配置推送出现问题这类事儿,而且也能减少研发动态线程池组件的难度工作量。线程池运行过程中的各项指标一般感知不到;

方志朋的博客 74

【2022年2月半月总结-第六周】

本文章为第六周半月总结,是二月份半个月来学习事务的总结: 第五周内容: 要知道Arraylist的优点,扩容机制,failfast机制(对应的failsafe机制) 要知道类加载的三个过程,以及什么情况下触发类的初始化,同时了解类初始化时期的字节码指令的位置。 知道学习了多态原理hsdb工具 重写与重载 知道计算机网络知识:tcp协议的延迟分析(为什么三次握手),dns解析,https加密(公钥,密钥,对称加密) spring mvc核心组件(dispatchServlet,ha

qq_43398404的博客 403

招银网络Java后端笔试题

1、MySQL的索引有什么数据结构?Hash与B+tree有什么区别 2、Spring MVC的执行流程是怎样的,请详述一下 3、怎样实现分布式锁?有哪些方式实现? 4、实现线程有什么方式?线程有哪些状态状态之间是怎样转换的? 5、如何优化SQL、优化数据库 6、redis的数据过期过期策略是怎样的 7、nginx用来做什么?请大概说下 8、MyBatis的#与$有什么区别,ret...

qq_41303352的博客 8663

2026年Java面试全攻略:AI集成、JVM调优与高并发实战

Java作为企业级应用开发的核心技术,其知识体系涵盖从基础语法到分布式架构的多个层面。理解JVM内存模型垃圾回收机制是性能优化的基础,而并发编程中的线程安全与锁机制直接影响系统稳定性。这些核心技术通过SpringBoot等框架实现快速开发,并在高并发场景下体现技术价值。随着AI大模型技术的普及,Java应用集成智能能力成为新的技术趋势。本文基于当前热门的AI大模型集成JVM调优等热点,系统梳理Java面试中的核心考点,帮助开发者构建完整的知识体系,应对实际业务场景的技术挑战。

weixin_34095889的博客 418

Java 面试八股文全景攻略:深度拆解核心知识体系与高频考点(2025全新整理版)

集合源码、IO/NIO、新特性:线程池JUC工具、锁机制:内存模型、GC算法、调优实战:微服务、消息队列、分布式事务:高并发、高可用、缓存策略。

2401_83384536的博客 1365

springboot配置线程池-高并发场景

1.编写配置文件 package com.hbedu.search.hbsearch.utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Bean; import org.springframework.conte...

格赚 6万+

SpringBoot线程池创建、@Async配置步骤及注意事项

点击上方“Java知音”,选择“置顶公众号”技术文章第一时间送达!作者:Musclehengblog.csdn.net/Muscleheng/article/details/814096...

Java知音 2281

深入理解线程池的构造方法以及底层工作原理

/** * * @param corePoolSize 线程池核心线程数,当提交一个任务时,线程池创建一个新线程执行任务,直到当前线程数等于corePollSize; * 如果当前线程数为corePoolSize,继续提交的任务会被保存到阻塞队列中,等待被执行; * 如果执行了线程池的prestartAllCoreThread()方法时,线程池会提前创建并启动所有的核心线程 ...

一个菜鸟的博客 321

JUC线程池

java.util.concurrent包(简称:JUC)。JUC主要是让开发者在多线程编程中更加简单、方便一些。通过JDK内置了一些类、接口、关键字,补充完善了JDK对于并发编程支持的“短板”。(1)Executor:线程池(2)Atomic:原子操作类(3)Lock:锁(4)Tools:信号量工具类(4)并发集合:提供了线程安全的集合类。

weixin_53455615的博客 930

JUC多线程:线程池创建及工作原理 Executor 框架

一、什么是线程池线程池主要是为了解决 新任务执行时,应用程序为任务创建一个新线程 以及 任务执行完毕时,销毁线程所带来的开销。通过线程池,可以在项目初始化时就创建一个线程集合,然后在需要执行新任务时重用这些线程而不是每次都新建一个线程,一旦任务已经完成了,线程回到线程池中并等待下一次分配任务。 二、创建线程池: 1、通过Executors创建线程池: 在JUC包中的Executors中,提供了一些静态方法,用于快速创建线程池,常见的线程池有: (1)newSingleThreadExecutor:创建

张维鹏的博客 1万+

线程池配置合理的线程数(七)

线程池的线程数配置,主要看服务器是属于以下哪种类型: (1)CPU密集型。 (2)IO密集型。 一:CPU密集型算法: (1)名称解释:CPU密集型的意思是该任务需要大量的运算,而没有阻塞,CPU一直全速运行。CPU密集任务只有在真正多核CPU上才可能得到加速(通过多线程),而在单核CPU上,无论你开几个模拟的多线程该任务都不可能得到加速,因为CPU总的运算能力就那些。 (2)计算...

Zhang895341748的专栏 860

任务监控系统 安全智能管控系统 闲鱼智能监控机器人.zip

可视化Web界面: 提供完整的Web UI,支持任务的可视化管理、AI标准在线编辑、运行日志实时查看结果筛选浏览,无需直接操作命令行配置文件。AI驱动的任务创建: 只需用自然语言描述你的购买需求,即可一键创建包含复杂筛选逻辑的全新监控任务。多任务并发: 通过 config.json 同时监控多个关键词,各任务独立运行,互不干扰。实时流式处理: 发现新商品后,立即进入分析流程,告别批处理延迟。深度AI分析: 集成多模态大语言模型(如 GPT-4o),结合商品图文卖家画像进行深度分析,精准筛选。高度可定制: 每个监控任务均可配置独立的关键词、价格范围、筛选条件AI分析指令 (Prompt)。即时通知: 支持通过 ntfy.sh、企业微信机器人 Bark,将符合AI推荐的商品立即推送到你的手机或桌面。定时任务调度: 支持 Cron 表达式,可为每个任务设置独立的定时执行计划。Docker 一键部署: 提供 docker-compose 配置,实现快速、标准化的容器化部署。健壮的反爬策略: 模拟真人操作,包含多种随机延迟用户行为,提高稳定性。

SCUT-HEAD头部检测数据集(Pascal VOC标准)

数据集介绍SCUT-HEAD是一个大规模的头部检测数据集,人头检测计数本数据集包含AB两部分,我将AB两部分合并在了一起,并遵循Pascal VOC标准。数据描述数据集包括4405张标有111251个头部的图像。该数据集由两部分组成。A部分包括从某大学教室的监控视频中抽出的2000张图像,其中有67321个头像的注释。B部分包括从互联网上抓取的2405张图片,有43930个头像被标注。我们用xmin、ymin、xmaxymax坐标标记了每个可见的头像,并确保注释覆盖整个头像,包括被遮挡的部分,但没有额外的背景。PartAPartB都被分为训练测试部分。我们的数据集遵循Pascal VOC的标准。

上一篇: 【2022最新Java面试宝典】—— BIO、NIO、AIO、Netty面试题(35道含答案)
下一篇: 【JUC并发编程】AQS底层实现原理(源码解读/ 核心参数/ 公平锁/ 非公平锁/ 锁池/ 等待池)
超级码里喵
超级码里喵 优质创作者: Java技术领域 优质创作者: Java技术领域
博客等级 码龄11年 5万+粉丝 217原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

超级码里喵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值