线程池相关小结

1991-2020年气候背景数据集 2011 年,国家气象信息中心对 1951-2010 年 2400 余个地面站气温、气压、降水、湿度、日照等 19 大要素项的定时观测资料和日极值资料中由数字化过程中引起的系统性问题(例如数字化遗漏、整段拷贝等问题)进行质量检测、质量控制和错误数据的更正,形成较高质量的地面基础资料集。1991-2020年中国地面气候值数据集提供了中国2438个站点的气温、降水、气压、风向风速、相对湿度、水汽压、云、天气现象、能见度、蒸发、积雪、地温、冻土、日照共14个要素的气候背景信息。数据时间:30年平均。 阅读详情

目录

1、是什么?

2、为什么?

3、怎么用?

4、总结


1、是什么?

线程池(Thread Pool)是一种基于池化思想管理线程的工具,经常出现在多线程服务器中,如MySQL。

2、为什么?

线程过多会带来额外的开销,其中包括创建销毁线程的开销、调度线程的开销等等,同时也降低了计算机的整体性能。线程池维护多个线程,等待监督管理者分配可并发执行的任务。这种做法,一方面避免了处理任务时创建销毁线程开销的代价,另一方面避免了线程数量膨胀导致的过分调度问题,保证了对内核的充分利用。

使用线程池可以带来一系列好处:

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

3、怎么用?

3.1 创建

方式一:使用JDK中Executors工具类4种方式创建(不推荐)

// 1.单个线程的线程池
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
// 2.固定线程数的线程池
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(corePoolSize);
// 3.可缓存的线程池
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
// 4. 实现调度的线程池
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(corePoolSize);
...

通过JDK提供的Executors工具类创建的几种方式都不推荐,因为底层使用的阻塞队列或者是最大线程数都是Integer的最大值,可能会导致OOM。

方式二:实际项目中使用线程池按照阿里巴巴开发手册中推荐的创建线程池的方式(推荐)

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

// 使用ThreadPoolExecutor几种带参数的构造方法创建线程池
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(....);

3.2 线程池参数含义

ThreadPoolExecutor中提供了多种重载的构造函数,其中的七大参数的含义,我们可以在JDK中ThreadPoolExecutor类中的方法源码的注释中看到:

/**
 * 给定初始化参数的创建一个新的线程池ThreadPoolExecutor
 * Creates a new {@code ThreadPoolExecutor} with the given initial
 * parameters.
 *
 * (1)corePoolSize:核心线程数,线程池中要保留的最小线程数,即使他们都是空闲状态,
 *  也不会被清理,除非设置了allowCoreThreadTimeOut=true
 * @param corePoolSize the number of threads to keep in the pool, even
 *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
 *
 * (2)maximumPoolSize:最大线程数,线程池中允许创建的最大线程数量
 * @param maximumPoolSize the maximum number of threads to allow in the
 *        pool
 *
 * (3)keepAliveTime:保留存活时间,当线程数量大于核心线程数,这些超出的空闲状态的线程
 *  在线程池中等待新任务到来的所能存活的最大时间
 * @param keepAliveTime when the number of threads is greater than
 *        the core, this is the maximum time that excess idle threads
 *        will wait for new tasks before terminating.
 *
 * (4)unit:时间单位,keepAliveTime 参数的时间单位
 * @param unit the time unit for the {@code keepAliveTime} argument
 *
 * (5)workQueue:工作队列,这个队列被用来保存被执行前的任务,这个队列只会保存
 *  被提交的 Runnable状态的任务。
 * @param workQueue the queue to use for holding tasks before they are
 *        executed.  This queue will hold only the {@code Runnable}
 *        tasks submitted by the {@code execute} method.
 *
 * (6)threadFactory:当任务被执行时用来创建一个新的线程的工厂
 * @param threadFactory the factory to use when the executor
 *        creates a new thread
 *
 * (7)handler:拒绝策略,当因为达到线程池最大数量并且等待队列容量也满了的时候,
 *  处理被阻塞的新添加的任务策略
 * @param handler the handler to use when execution is blocked
 *        because the thread bounds and queue capacities are reached
 * @throws IllegalArgumentException if one of the following holds:<br>
 *         {@code corePoolSize < 0}<br>
 *         {@code keepAliveTime < 0}<br>
 *         {@code maximumPoolSize <= 0}<br>
 *         {@code maximumPoolSize < corePoolSize}
 * @throws NullPointerException if {@code workQueue}
 *         or {@code threadFactory} or {@code handler} is null
 */
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.corePoolSize = corePoolSize;
    this.maximumPoolSize = maximumPoolSize;
    this.workQueue = workQueue;
    this.keepAliveTime = unit.toNanos(keepAliveTime);
    this.threadFactory = threadFactory;
    this.handler = handler;
}

3.3 线程池任务的执行过程

当用户提交一个任务到线程池中,是如何被执行的呢?所有任务最终都会调用execute方法来完成。

/**
 * Executes the given task sometime in the future.  The task
 * may execute in a new thread or in an existing pooled thread.
 *
 * If the task cannot be submitted for execution, either because this
 * executor has been shutdown or because its capacity has been reached,
 * the task is handled by the current {@code RejectedExecutionHandler}.
 *
 * @param command the task to execute
 * @throws RejectedExecutionException at discretion of
 *         {@code RejectedExecutionHandler}, if the task
 *         cannot be accepted for execution
 * @throws NullPointerException if {@code command} is null
 */
public void execute(Runnable command) {
    if (command == null)
        throw new NullPointerException();
    /*
     * Proceed in 3 steps:
     *
     * 1. If fewer than corePoolSize threads are running, try to
     * start a new thread with the given command as its first
     * task.  The call to addWorker atomically checks runState and
     * workerCount, and so prevents false alarms that would add
     * threads when it shouldn't, by returning false.
     *
     * 2. If a task can be successfully queued, then we still need
     * to double-check whether we should have added a thread
     * (because existing ones died since last checking) or that
     * the pool shut down since entry into this method. So we
     * recheck state and if necessary roll back the enqueuing if
     * stopped, or start a new thread if there are none.
     *
     * 3. If we cannot queue task, then we try to add a new
     * thread.  If it fails, we know we are shut down or saturated
     * and so reject the task.
     */
    int c = ctl.get();
    if (workerCountOf(c) < corePoolSize) {
        if (addWorker(command, true))
            return;
        c = ctl.get();
    }
    if (isRunning(c) && workQueue.offer(command)) {
        int recheck = ctl.get();
        if (! isRunning(recheck) && remove(command))
            reject(command);
        else if (workerCountOf(recheck) == 0)
            addWorker(null, false);
    }
    else if (!addWorker(command, false))
        reject(command);
}

通过查看代码和注释信息,我们可以简单总结下任务被提交到线程池后的执行过程大致是:

  1.  首先检查线程池的状态,如果不是RUNNING,则直接拒绝,线程池要保证在RUNNING的状态下执行任务;
  2. 如果工作线程数小于核心线程数,则创建并启动一个新线程来执行新提交的任务,即使现在有空闲的核心线程,也会创建新线程;
  3.  如果工作线程数大于或等于核心线程数,且线程池内的工作等待队列未满,则将任务添加到该阻塞队列中;
  4. 如果工作线程数大于或等于核心线程数,并且工作线程数小于最大线程数,且工作队列已满,则创建并启动一个新线程来执行新提交的任务; 5. 如果工作线程数大于或等于最大线程数,并且线程池内的阻塞队列已满,则根据拒绝策略来处理该任务,默认的处理方式是直接抛异常;

流程图如下:

3.4 如何设置线程池的参数

具体的线程池参数配置要根据业务场景需要来配置,并没有统一的配置参数;其中线程池最核心的参数就是线程池中的线程数量,一种比较广泛使用的方式是:

CPU 密集型任务(N+1): 这种任务消耗的主要是 CPU 资源,可以将线程数设置为 N(CPU 核心数)+1,比 CPU 核心数多出来的一个线程是为了防止线程偶发的缺页中断,或者其它原因导致的任务暂停而带来的影响。一旦任务暂停,CPU 就会处于空闲状态,而在这种情况下多出来的一个线程就可以充分利用 CPU 的空闲时间。

I/O 密集型任务(2N): 这种任务应用起来,系统会用大部分的时间来处理 I/O 交互,而线程在处理 I/O 的时间段内不会占用 CPU 来处理,这时就可以将 CPU 交出给其它线程使用。因此在 I/O 密集型任务的应用中,我们可以多配置一些线程,具体的计算方法是 2N。

如何判断是 CPU 密集任务还是 IO 密集任务?

CPU 密集型简单理解就是利用 CPU 计算能力的任务比如你在内存中对大量数据进行排序。单凡涉及到网络读取,文件读取这类都是 IO 密集型,这类任务的特点是 CPU 计算耗费时间相比于等待 IO 操作完成的时间来说很少,大部分时间都花在了等待 IO 操作完成上。

4、总结

有关线程池的设计细节还有很多,比如线程池的状态和线程数是通过AtomicInteger原子类中的一个int值来存储的,要想了解线程池的具体实现细节,最好的办法就是去查看JDK中的源码和注释,里面有详细的解析,本文只是简单总结一下线程池的常见知识。

参考地址:

JDK源码

Java线程池实现原理及其在美团业务中的实践:https://tech.meituan.com/2020/04/02/java-pooling-pratice-in-meituan.html

三分钟弄懂线程池执行过程:https://juejin.cn/post/6866054685044768782

java线程池学习总结.md:https://github.com/Snailclimb/JavaGuide/blob/master/docs/java/multi-thread/java%E7%BA%BF%E7%A8%8B%E6%B1%A0%E5%AD%A6%E4%B9%A0%E6%80%BB%E7%BB%93.md#%E4%B8%83-%E7%BA%BF%E7%A8%8B%E6%B1%A0%E5%A4%A7%E5%B0%8F%E7%A1%AE%E5%AE%9A

【CanMV K210】AI 视觉 MNIST 手写数字识别与分类推理 本文介绍了基于CanMV K210开发板的MNIST手写数字识别实验。实验通过摄像头采集图像,经过开窗、灰度化、缩放、反色等预处理后,使用KPU神经网络加速器运行MNIST分类模型,最终在LCD上显示识别结果。重点讲解了分类模型与检测模型的区别、图像预处理流程以及KPU推理结果的解析方法。实验帮助理解从图像采集到分类输出的完整AI视觉处理链路,并提供了调试思路和硬件连接说明。 阅读详情

相关推荐

sdio wifi 移植

介绍 简单来说,sdio起源自sd标准,顾名思义就是sd的IO接口(interface)的意思,更具体的说明,sd本来是记忆卡的标准,但是现在也可以把SD卡拿来插上一些外围设备接口使用,这个就是就叫做sdio。 而且sdio本身是一种相当单纯的技术,通过sd的IO引脚来连接外部外围,并且通过sd的IO数据接位与外围传输数据,而且sd协会也推出很完整的sdio stack 驱动程序,使得sdio外围得开发与应用变得非常热门 这里我们要移植的是RTL8822cs的sdio WiFi 模块,将其移植到rk3

Enosji的博客 9609

线程上下文切换

多线程编程中,一般线程的个数都大于CPU的个数,而一个CPU核心在任意时刻只能被一个线程使用,为了让这些线程都能得到有效执行,CPU才去的策略是为每个线程分配时间片并轮转的形式。当一个线程的时间用完时就会重新处于就绪状态,CPU的使用交给其他线程,完成一次上下文切换。 概括来说就是:当前任务在执行完 CPU 时间片切换到另一个任务之前会先保存自己的状态,以便下次再切换回这个任务时,可以再加载这个任务的状态。任务从保存到再加载的过程就是一次上下文切换。 上下文切换通常是计算密集型的。也就是说,它需要相当可观的

Jhon1994的博客 411

uCOS中的消息邮箱(:task与task之间传递一个数据(数据缓冲区))

程序需求,需要完成task与task之间  字符数组的数据传输 比如:在ucos中,串口2接收的字符数组是不定时的&不定长的;只有当接收到数据的时候_才将数据赋值给新数组 具体的程序示意如下: 图1:消息邮箱测试中的     向消息邮箱发送消息(OSMboxPost(Str_Box,(void*)rec);//发送消息--(向 消息邮箱_msg_key发送消息) ),实际项目需求的

faguoduifangui的博客 4540

【Java笔记】多线程1:线程池大小为什么设置N+1或2N?CPU密集型?IO密集型?

需要注意的是,N是最大并行数,而不是“X核CPU”的X。一般我们会听到例如“4核8线程”的说法,这里的8就是N,虽然只有4个CPU(核心),但是可以利用超线程技术把原来CPU4个线程虚拟成8个。首先要明确,2N跟N+1都是经验值,大家能明白大概的逻辑就行。

Hansdas的博客 2498

电化学阻抗谱(EIS)在锂离子电池中的应用

摘要电化学阻抗谱(electrochemical impedance spectroscopy, EIS)是一种重要的电化学测试方法,在锂离子电池动力学反应机理研究及动力学参数测量等方面具有广泛的应用。在锂离子电池运行过程中,各反应步骤的动力学参数及时间常数不同,而EIS可以在较宽的频率范围内对体系施加小幅正弦激励信号,使得在特定频率下突出特定时间常数的电极过程,从而将复杂的电极过程分离,实现单一电极过程动力学的分析。通过对交流阻抗信息的研究,也可以为锂离子电池及其他电池的应用与管理、电化学过程设计及电极材

qiushireader的博客 2650

C# Winform使用Monaco打造代码编辑器

本文介绍了如何在Winform项目中集成Monaco代码编辑器。通过NuGet安装WebView2控件,创建monaco-editor.html文件加载编辑器,并实现与C#代码的交互。关键步骤包括:初始化WebView2环境、配置Monaco编辑器参数、设置代码变更监听事件以及处理C#与JavaScript之间的通信。注意事项提示了依赖库安装问题的解决方法。该方案实现了功能完整的代码编辑器,支持代码自动保存和实时显示功能。

遇见--专栏 346

线程池大小的设置,判断 CPU 密集任务还是 IO 密集任务?G1 收集器有哪些特点?

今天来谈谈Java的几个少见到,而且还比较重要的几个问题;

weixin_44797327的博客 1287

TIA protal与SCL从入门到精通(4)——软件单元使用

平台: TIA portal 15.1 1.添加软件单元 添加软件单元如下图: 关于软件单元使用基本限制,看如下文章即可 TIA protal与SCL从入门到精通(3)——软件单元基本介绍 每个软件单元是一个独立结构,所以每个软件单元的运行方式与实际PLC类似,所以首先添加主函数块: 注意:无论系统是否是具有并发性(这里不要混淆并行与并发的概念),在PLC所有主函数执行总是按主函数依次完成...

苦走一口田 7375

面试遗留问题

美团二面 1.浮点型怎么比较 2.cpu密集型为什么线程数n+1 3.两个栈最多维护n+1队列 4.计算机内存 分页 分段 5.hashmap怎么线程不安全 ?怎么让他线程安全 6. tcp udp 实现牛客 代码段 7.泛型的本质 商汤一面 1. post 和 put 底层区别,rest架构 2. 两个服务器怎么共享session 3. 线程 waiting 和 sleep区别 小米一面 1. 同步 和 阻塞 区别 ;BIO和NIO区别 2. TCP的最多能装多少字节 小米二面 AQS底层锁l.

yuyan_jia的博客 237

【Simulink教程案例18】基于simulink的基础OFDM+64QAM发射接收链路仿真

OFDM(Orthogonal Frequency Division Multiplexing)即正交频分复用技术,实际上OFDM是MCM(Multi Carrier Modulation),多载波调制的一种。通过频分复用实现高速串行数据的并行传输, 它具有较好的抗多径衰落的能力,能够支持多用户接入。OFDM技术由MCM(Multi-Carrier Modulation,多载波调制)发展而来。OFDM技术是多载波传输方案的实现方式之一,它的。

FPGA/MATLAB学习教程/源码/项目合作开发 1986

手把手教你学simulink(85.6)--非线性控制:滑模控制场景实例:基于Simulink建模仿真的滑模控制(Sliding Mode Control, SMC)在无人机自主飞行控制系统中的应用

首先,在MATLAB命令窗口中定义系统的参数和状态空间模型。matlab深色版本% 系统参数m = 1.5;% 无人机质量 (kg)g = 9.81;% 重力加速度 (m/s^2)% 惯性矩阵 (kg*m^2)% 初始条件pos0 = [0;0;0];% 初始位置 (m)vel0 = [0;0;0];% 初始速度 (m/s)0;0];% 初始姿态角 (rad)0;0];% 初始角速度 (rad/s)

MHD0815的博客 649

【线程池】线程池的corePoolSize大小为什么设置为N+1或2N?

线程池的corePoolSize大小为什么设置为N+1或2N?

Arcus 887

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

JAVA面试小结四十五:线程池(ThreadPool)相关工作原理?

这些参数共同决定了线程池的工作方式,包括如何分配任务,如何管理线程的生命周期,以及如何处理超出处理能力的任务。正确地设置这些参数可以帮助优化线程池的性能和资源利用率。通过这种方式,线程池能够高效地管理线程和任务,避免频繁创建和销毁线程,从而减少资源消耗,提高系统性能。同时,通过合理的配置,可以使得线程池适应各种不同的并发场景。

之乎者也·的博客 167

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

java 线程池 包_Java并发包下线程池类小结

并发包下的线程池技术虽然常用,但是知识点较多易忘。所以,参考网络资源做了一个小结,便于复习。1.Executor接口用于执行已提交的Runnable任务。Paste_Image.png2.ExecutorService接口继承自Executor接口。Paste_Image.png3.ScheduledExecutorService接口继承自ExecutorService接口,在给定的延迟后执行任务...

weixin_39861955的博客 171

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

快速了解Python并发编程的工程实现(上)

关于我 编程界的一名小程序猿,目前在一个创业团队任team lead,技术栈涉及Android、Python、Java和Go,这个也是我们团队的主要技术栈。 0x00 前言 在前面的文章中对Python协程的概念和实现做了简单地介绍。为了对Python并发编程有更加全面地认识,我也对Python线程和进程的概念和相关技术的使用进行了学习,于是有了这篇文字。 0x01 线程与进程 当我们在手机或...

weixin_34186128的博客 147

多线程服务器分析——Reactor线程模型和性能分析(四)

当请求到达网关层时,发现客户端是的请求是上传文件,那么就开始接收,接收一个分块就传递给数据管理层,直到最后一个分块在数据管理层写入成功或者中途某个分块处理失败,数据管理层将该信息返回给网关层,如果失败网关层直接返回用户写入失败,如果成功则向元数据管理层写入元数据,元数据管理层写入成功再返回给网关,直到这时网关层才能返回给用户该文件写入成功的响应。本章根据一个实际的分布式存储系统的写入文件的案例,结合之前讲述的线程模型,实现了一个完整的多线程任务的执行逻辑。

weixin_43977379的博客 1381

Java线程池知识点小结

查看调用发现,原来后台有一个处理字符串并将内容写入到文本文件的操作,综合来看相当于一个计算型任务,由于这个任务不是很经常出现,所以开发者就设置两个线程,并且为了让任务能够正确完成,拒绝策略也是使用。上文提到使用execute提交无返回值的任务,这样异常就会被感知,但还需要注意的是频繁的抛出异常会让线程消亡,导致线程池每次执行新任务时回去创建新的线程。所以我们建议,对于线程池的中的任务尽可能不要用异常来处理逻辑,对于可以预见的异常,我们建议手动处理返回,避免线程销毁再创建的开销。的线程数继续处理应急任务呢?

sc35262的博客 915

java线程池小结

1.线程池相关的类 1.Executor接口,将任务提交与任务的细节解耦开。Executor接口只有一个execute方法 public interface Executor { /** * Executes the given command at some time in the future. The command * may execute in a ne...

bitcarmanlee的博客 417

线程池创建相关

线程池的创建方式 常见的创建线程池的三种方式 Executors.newFixedThreadPool(int):创建拥有指定线程数的线程池。当没有空闲线程时,任务会进入等待队列等待。 Executors.newSingleThreadExecutor():创建只有一个线程数的线程池。当没有空闲线程时,任务会进入等待队列等待。 Executors.newCachedThreadPool():创建可自动扩容线程数的线程池。没有空闲线程时会创建线程去执行任务,当60s内没有新任务线程会释放。 三种方式的底层

张鹏的博客 769

线程池小结(JDK8)

1、线程池的好处 降低资源消耗(重复利用已创建的线程减少创建和销毁线程的开销) 提高响应速度(无须创建线程) 提高线程的可管理性 2、相关类图 JDK5以后将工作单元和执行机制分离开来,工作单元包括Runnable和Callable;执行机制由Executor框架提供,管理线程的生命周期,将任务的提交和如何执行进行解耦。Executors是一个快速得到线程池的工具类,相关的类图...

weixin_30825581的博客 202

ThreadPool线程池 小结

ThreadPool类提供一个线程池,该线程池可用于发送工作项、处理异步 I/O、代表其他线程等待以及处理计时器 线程池通过为应用程序提供一个由系统管理的辅助线程池使您可以更为有效地使用线程。一个线程监视排到线程池的若干个等待操作的状态。当一个等待操作完成时,线程池中的一个辅助线程就会执行对应的回调函数 托管线程池中的线程为后台线程,即它们的 IsBackground 属性为 ...

154

线程池小结

常见子类 ThreadPoolExecutor * void execute(Runnable command):执行任务/命令,没有返回值,一般用于执行Runnable * <T>Future<T> submit(Callable<T> task):执行任务,有返回值,一般用来执行Callable * void shutdown(): 关闭连接池。3.Executors:工具类 线程池的工厂类,用于创建并返回不同类型的线程池。1.提高响应速度(减少了创建新线程的时间)

qq_53801214的博客 300

java线程池的面试题_献给准备面试的你,Java线程and线程池面试题小结

最近这几天一直在整理Java相关的面试题,“金九银十”是求职的最佳时间,但是现在的“银十”也已经过去了一半的时间,相信现在还在为面试四处奔波的小伙伴已经很疲惫了吧,下面就来减轻你负担,Java线程和线程池相关的面试题整理给大家,减轻你准备面试的负担。丑话说在前面,我“丑”我先说,嘿嘿。因为篇幅有限,所以这次的文章不会包含面试题的所有的内容,在这里求大家点一波关注啦!以后会持续更新哒!1、为什么用线...

weixin_42140716的博客 1212

线程池整理汇总

线程池

weixin_40017062的博客 1255

android:线程池和AsyncTask使用小结,阿里、百度等大厂技术面试题汇总

strings) {//对应第一个参数。// protected void onCancelled(String s) {//对应第三个参数。创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。if (isCancelled()) //Task被取消了,不再继续执行后面的代码。if (isCancelled()) //Task被取消了,不再继续执行后面的代码。if (isCancelled())//Task被取消了,马上退出循环。

m0_60388292的博客 957

线程池的一点小结

1,背景:经常创建和销毁、使用量特别大的资源,比如并发情况下的线程,对性能影响很大。 2,思路:提前创建好多个线程,放入线程池中,使用时直接获取,使用完放回池中。 可以避免频繁创建销毁、实现重复利用。类似生活中的公共交通工具。 3,好处: (1)提高响应速度(减少了创建新线程的时间) (2)降低资源消耗(重复利用线程池中线程,不需要每次都创建) (3)便于线程管理(....) corePoolSize:核心池的大小 maximumPoolSize:最大线程数 ...

qq_57753433的博客 104
上一篇: Docker方式安装Consul配置中心
下一篇: IDEA常用快捷键总结
ProgrammingWay
博客等级 码龄9年 58粉丝 21原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值