一.情景复现 昨天,公司一个同事,急急忙忙的跑过来找我,说他的项目,出现了一个非常诡异的BUG,不知道什么情况? 同事:我用五个线程计算学生各个科目的成绩,最后汇总,本地都是正常的,但是一到测试环境就少了一科成绩,也没抛出异常,什么鬼? 油七:任务线程怎么做的?线程异常处理了吗?为啥不打印日志呢?灵魂三连击,哈哈哈(开玩笑的,这不是我的处事风格) 油七:行,咱们先看一下代码...,一顿扫描占卜之后,大致知道啥情况了. 同事:哥,我这程序还有救吗,客户下了死命令,今天解决啊. 油七:没事,小伙子,…
1.背景介绍 上一篇从整体上介绍了Executor接口,从上一篇我们知道了Executor框架的最顶层实现是ThreadPoolExecutor类,Executors工厂类中提供的newScheduledThreadPool.newFixedThreadPool.newCachedThreadPool方法 其实本质上也只是ThreadPoolExecutor的构造函数参数不同而已.通过传入不同的参数,就可以构造出适用于不同应用场景下的线程池,那么它的底层原理是怎样实现的呢,这篇就来介绍下Thre…
写在前面 之前探索tomcat7启动的过程中,使用了线程池(ThreadPoolExecutor)的技术 public void createExecutor() { internalExecutor = true; TaskQueue taskqueue = new TaskQueue(); TaskThreadFactory tf = new TaskThreadFactory(getName() + "-exec-", daemon, getThreadPriority());…
前言: 在刚学Java并发的时候基本上第一个demo都会写new Thread来创建线程.但是随着学的深入之后发现基本上都是使用线程池来直接获取线程.那么为什么会有这样的情况发生呢? new Thread和线程池的比较 每次new Thread是新建了线程对象,并且不能重复使用,为什么不能重复使用?因为new是相当于在内存中独立开辟一个内存来让该线程运行,所以只能释放线程资源和新建线程,性能差.而使用线程池,可以重复使用存在的线程,减少对象的创建,消亡的开销,性能较好 线程缺乏统一管理,可能无限…
TestThreadPoolExecutorMain package core.test.threadpool; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** * ThreadPoolExecutor 线程池 * 构造函数参数 * * 1.corePoolSize 核心…
自定义ThreadPoolExecutor线程池 自定义线程池需要遵循的规则 [1]线程池大小的设置 1.计算密集型: 顾名思义就是应用需要非常多的CPU计算资源,在多核CPU时代,我们要让每一个CPU核心都参与计算,将CPU的性能充分利用起来,这样才算是没有浪费服务器配置,如果在非常好的服务器配置上还运行着单线程程序那将是多么重大的浪费.对于计算密集型的应用,完全是靠CPU的核数来工作,所以为了让它的优势完全发挥出来,避免过多的线程上下文切换,比较理想方案是: ​ 线程数 = CPU核数+1,…
作者:小傅哥 博客:https://bugstack.cn Github:https://github.com/fuzhengwei/CodeGuide/wiki 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 人看手机,机器学习! 正好是2020年,看到这张图还是蛮有意思的.以前小时候总会看到一些科技电影,讲到机器人会怎样怎样,但没想到人似乎被娱乐化的东西,搞成了低头族.大肚子! 当意识到这一点时,其实非常怀念小时候.放假的早上跑出去,喊上三五个伙伴,要不下河摸摸鱼.弹弹玻璃球.打打p…
本文章对ThreadPoolExecutor线程池的底层源码进行分析,线程池如何起到了线程复用.又是如何进行维护我们的线程任务的呢?我们直接进入正题: 首先我们看一下ThreadPoolExecutor类的源码 1 public ThreadPoolExecutor(int corePoolSize, 2 int maximumPoolSize, 3 long keepAliveTime, 4 TimeUnit unit, 5 BlockingQueue<Runnable> workQueue…
摘要:从手写线程池开始,逐步的分析这些代码在Java的线程池中是如何实现的. 本文分享自华为云社区<手写线程池,对照学习ThreadPoolExecutor线程池实现原理!>,作者:小傅哥. 谢飞机,小记!,上次吃亏在线程上,这可能一次坑掉两次吗! 谢飞机:你问吧,我准备好了!!! 面试官:嗯,线程池状态是如何设计存储的? 谢飞机:这!下一个,下一个! 面试官:Worker 的实现类,为什么不使用 ReentrantLock 来实现呢,而是自己继承AQS? 谢飞机:我-! 面试官:那你简述下,…
jdk1.7.0_79  在上一篇<ThreadPoolExecutor线程池原理及其execute方法>中提到了线程池ThreadPoolExecutor的原理以及它的execute方法.本文解析ThreadPoolExecutor#submit. 对于一个任务的执行有时我们不需要它返回结果,但是有我们需要它的返回执行结果.对于线程来讲,如果不需要它返回结果则实现Runnable,而如果需要执行结果的话则可以实现Callable.在线程池同样execute提供一个不需要返回结果的任务执行,而…
官方+白话讲解Executors.ThreadPoolExecutor线程池使用 Executors:JDK给提供的线程工具类,静态方法构建线程池服务ExecutorService,也就是ThreadPoolExecutor,使用默认线程池配置参数. 建议:对于大用户,高并发,不易掌控的项目,不建议使用Executors来创建线程池对象. 对于易于掌控且并发数不高的项目,可以考虑Executors. ThreadPoolExecutor:线程池对象,实现ExecutorService接口,可以自…
主要是自己在项目中(中小型项目) 有支付下单业务(只是办理VIP,没有涉及到商品库存),目前用户量还没有上来,目前没有出现问题,但是想到如果用户量变大,下单并发量变大,可能会出现一系列的问题,趁着空闲时间,做了这个demo测试相关问题. 可能遇到的问题如下: 1.订单重复 2.高并发下,性能变慢 解决方式:ThreadPoolExecutor线程池 + Queue队列 开发工具:IDEA 15 1.首先是springBoot的项目框架如下 2.业务测试流程涉及的类,如下 BusinessThre…
1. 引言 合理利用线程池能够带来三个好处. 第一:降低资源消耗.通过重复利用已创建的线程降低线程创建和销毁造成的消耗. 第二:提高响应速度.当任务到达时,任务可以不需要等到线程创建就能立即执行. 第三:提高线程的可管理性.线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控. 但是要做到合理的利用线程池,必须对其原理了如指掌. 2. 线程池的使用 线程池的创建 我们可以通过java.util.concurrent.ThreadPo…
jdk1.7.0_79  对于线程池大部分人可能会用,也知道为什么用.无非就是任务需要异步执行,再者就是线程需要统一管理起来.对于从线程池中获取线程,大部分人可能只知道,我现在需要一个线程来执行一个任务,那我就把任务丢到线程池里,线程池里有空闲的线程就执行,没有空闲的线程就等待.实际上对于线程池的执行原理远远不止这么简单. 在Java并发包中提供了线程池类——ThreadPoolExecutor,实际上更多的我们可能用到的是Executors工厂类为我们提供的线程池:newFixedThread…
一.ThreadPoolExecutor的重要参数   corePoolSize:核心线程数 核心线程会一直存活,及时没有任务需要执行 当线程数小于核心线程数时,即使有线程空闲,线程池也会优先创建新线程处理 设置allowCoreThreadTimeout=true(默认false)时,核心线程会超时关闭 queueCapacity:任务队列容量(阻塞队列) 当核心线程数达到最大时,新任务会放在队列中排队等待执行 maxPoolSize:最大线程数 当线程数>=corePoolSize,且任务队…
我们知道,受限于硬件.内存和性能,我们不可能无限制的创建任意数量的线程,因为每一台机器允许的最大线程是一个有界值.也就是说ThreadPoolExecutor管理的线程数量是有界的.线程池就是用这些有限个数的线程,去执行提交的任务.然而对于多用户.高并发的应用来说,提交的任务数量非常巨大,一定会比允许的最大线程数多很多.为了解决这个问题,必须要引入排队机制,或者是在内存中,或者是在硬盘等容量很大的存储介质中.J.U.C提供的ThreadPoolExecutor只支持任务在内存中排队,通过Bloc…
更好的markDown阅读体验可直接访问我的CSDN博客:https://blog.csdn.net/u012881584/article/details/85221635 前言 线程池想必大家也都用过,JDK的Executors 也自带一些线程池.但是不知道大家有没有想过,如何才是最优雅的方式去使用过线程池吗? 生产环境要怎么去配置自己的线程池才是合理的呢? 今天周末,刚好有时间来总结一下自己所认为的'优雅', 如有问题欢迎大家指正. 线程池使用规则 要使用好线程池,那么一定要遵循几个规则:…
引言 Android的线程池概念来自于Java的Executor,真正的线程池实现为ThreadPoolExecutor.在Android中,提供了4类不同的线程池,具体下面会说到.为什么使用线程池呢?而不是使用Thread创建线程呢?因为使用线程池有以下几个优点: 重用线程池的线程,避免因为线程的创建和销毁所带来的性能开销 能有效控制线程池的最大并发数,避免线程之间抢占资源导致阻塞 能够对线程进行简单的管理,并提供定时执行以及指定间隔循环执行等功能 所以需要多次创建Thread时使用线程池较好…
1. 引言 合理利用线程池能够带来三个好处. 第一:降低资源消耗.通过重复利用已创建的线程降低线程创建和销毁造成的消耗. 第二:提高响应速度.当任务到达时,任务可以不需要等到线程创建就能立即执行. 第三:提高线程的可管理性.线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控. 但是要做到合理的利用线程池,必须对其原理了如指掌. 2. 线程池的使用 线程池的创建 我们可以通过java.util.concurrent.ThreadPo…
作为Executor框架中最核心的类,ThreadPoolExecutor代表着鼎鼎大名的线程池,它给了我们足够的理由来弄清楚它. 下面我们就通过源码来一步一步弄清楚它. 内部状态 线程有五种状态:新建,就绪,运行,阻塞,死亡,线程池同样有五种状态:Running, SHUTDOWN, STOP, TIDYING, TERMINATED. private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0)); private…
为什么使用线程池: 1.创建/销毁线程伴随着系统开销,过于频繁的创建/销毁线程,会很大程度上影响处理效率. 2.线程并发数量过多,抢占系统资源从而导致阻塞. 3.对线程进行一些简单的管理. 在java中,线程池的类为ThreadPoolExecutor,该类提供了四种构造方法: //五个参数的构造函数 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit…
一.简介 executor接口 executor接口在JDK的java.util.concurrent包下,它只有一个抽象方法: void execute(Runnable command); 这意味着,executor的接口实现主要是为了去执行Runnable.它的目的是将线程要处理的业务逻辑和线程的执行机制区分开来,你也不需要去显式地创建线程. ThreadPoolExecutor类 ThreadPoolExecutor直接继承AbstractExecutorService间接实现Execu…
目的 主要介绍ThreadPoolExecutor的用法,和较浅显的认识,场景的使用方案等等,比较忙碌,如果有错误还请大家指出 ThreadPoolExecutor介绍 ThreadPoolExecutor的完整构造方法的签名如下 ThreadPoolExecutor (int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, Thre…
一.源码分析(基于JDK1.6) ThreadExecutorPool是使用最多的线程池组件,了解它的原始资料最好是从从设计者(Doug Lea)的口中知道它的来龙去脉.在Jdk1.6中,ThreadPoolExecutor直接继承了AbstractExecutorService,并层级实现了ExecutorService和Executor接口. 1.Executor Executor是用来执行提交的Runnable任务的对象,并以接口的形式定义,提供一种提交任务(submission task…
Java是一门多线程的语言,基本上生产环境的Java项目都离不开多线程.而线程则是其中最重要的系统资源之一,如果这个资源利用得不好,很容易导致程序低效率,甚至是出问题. 有以下场景,有个电话拨打系统,有一堆需要拨打的任务要执行,首先肯定是考虑多线程异步去执行.假如我每执行一个拨打任务都new一个Thread去执行,当同时有1万个任务需要执行的时候,那么就会新建1万个线程,加上线程各种初始销毁等操作,这个消耗是巨大的.而其实往往实现这些功能的时候,并不是完全需要实时马上完成,只是希望在可控范围内尽…
keepAliveTime含义 看了很多文章觉得都不能把keepAliveTime的意思说的很明白,希望通过自己的理解把keepAliveTime说的明确一些 先引用一句我觉得相对说的比较明白的含义:当线程空闲时间达到keepAliveTime,该线程会退出,有两个疑问:1.线程为什么会空闲 2.线程为什么要退出 如果我们不能把线程池各个参数的来龙去脉都梳理清楚其实是很难明白keepAliveTime的含义的 我们来举例说明: 核心线程数10,最大线程数30,keepAliveTime是3秒 随…
一.简介 线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为: ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, RejectedExecutionHandler handler) corePoolSize: 线程池维护线程的最少数量 maximumPool…
1.线程池的作用 一方面当执行大量异步任务时候线程池能够提供较好的性能,在不使用线程池的时候,每当需要执行异步任务时候是直接 new 一线程进行运行,而线程的创建和销毁是需要开销的.使用线程池时候,线程池里面的线程是可复用的,不会每次执行异步任务时候都重新创建和销毁线程. 另一方面线程池提供了一种资源限制和管理的手段,比如可以限制线程的个数,动态新增线程等,每个 ThreadPoolExecutor 也保留了一些基本的统计数据,比如当前线程池完成的任务数目等. 2.ThreadPoolExecu…
这篇文章对ThreadPoolExecutor创建的线程池如何操作线程的生命周期通过源码的方式进行详细解析.通过对execute方法.addWorker方法.Worker类.runWorker方法.getTask方法.processWorkerExit从源码角度详细阐述,文末有彩蛋. exexcte方法 public void execute(Runnable command) { if (command == null) throw new NullPointerException(); in…
前言 在一次聚会中,我和一个腾讯大佬聊起了池化技术,提及到java的线程池实现问题,我说这个我懂啊,然后巴拉巴拉说了一大堆,然后腾讯大佬问我说,那你知道线程池有什么缺陷吗?我顿时哑口无言,甘拜下风,所以这次我再回来思考一下线程池的实现原理 源码分析 ThreadPoolExecutor构造器 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, Blo…