前言 使用无界队列的线程池会导致内存飙升吗?面试官经常会问这个问题,本文将基于源码,去分析newFixedThreadPool线程池导致的内存飙升问题,希望能加深大家的理解。...首先,我们先来看一下newFixedThreadPool方法的源码 newFixedThreadPool源码 public static ExecutorService newFixedThreadPool...由类图可以看到: LinkedBlockingQueue 是使用单向链表实现的,其有两个 Node,分别用来存放首、尾节点, 并且还有一个初始值为 0 的原子变量 count,用来记录 队列元素个数。...内存飙升问题结果揭晓 newFixedThreadPool线程池的核心线程数是固定的,它使用了近乎于无界的LinkedBlockingQueue阻塞队列。...当核心线程用完后,任务会入队到阻塞队列,如果任务执行的时间比较长,没有释放,会导致越来越多的任务堆积到阻塞队列,最后导致机器的内存使用不停的飙升,造成JVM OOM。
现象问题 最近看到线上的项目线程数过大的报警,开始还是不知道什么原因,因为很多项目都使用同样的线程池管理代码,认为那个项目是偶然的因素造成的,后来经过分析,发现线程数每天都在增加。...触发报警的代码大概如下: boolean start=true; public void doSomeThing(){ ExecutorService executorService = Executors.newFixedThreadPool...上面的代码存在两个问题: start是个主线程的变量,在主线程修改值,子线程的while循环不会停止 上述代码能够停止,因为在内部调用`Thread.sleep方法,导致线程内的变量刷新 newFixedThreadPool...ExecutorService executorService; Thread thread ; public void doSomeThing(){ executorService = Executors.newFixedThreadPool...&& thread.isAlive()) { thread.interrupt(); thread.join(2000); } } 最后的疑问 线程池在最后不使用后
既然newFixedThreadPool(1)也能保证创建只有一个线程运行的线程池,那么为什么还需要一个newSingleThreadExecutor()方法呢?带着这个问题我们来详细分析。...OrderTest { public static void main(String[] args) throws Exception{ ExecutorService es1 = Executors.newFixedThreadPool...3.本质区别 那么我们再看看这两个方法的源码: public static ExecutorService newFixedThreadPool(int nThreads) { return new...TimeUnit.MILLISECONDS, new LinkedBlockingQueue())); } 这样虽然底层仍然使用的是...分析了newFixedThreadPool(1)和newSingleThreadExecutor()的区别。实际上这两种设计是有原因的。而且对于后者这种将核心功能隔隔离的设计模式,非常值得我们借鉴。
文章目录 前言 一、线程池示例 二、newCachedThreadPool 线程池示例 三、newFixedThreadPool 线程池示例 三、newSingleThreadExecutor 线程池示例...; 一、线程池示例 ---- 创建 10 万线程 , 需要 10992 ms ; 使用线程池启动 10 万线程 , 仅需要 26 ms ; 线程池的效率比线程高几个数量级 ; 线程池示例...10992 ms 时间 , 使用线程池后 , 仅需要 26 ms , 这效率提升了好几个数量级 ; 等待线程执行结束 , 直接调用 Thread.join() 方法 , 等待线程池结束 ,...e.printStackTrace(); } } } } 执行结果 : 该线程池中创建了 100 个线程 , 执行 100 个任务 ; 三、newFixedThreadPool...public static void main(String[] args) { ExecutorService executorService2 = Executors.newFixedThreadPool
看这块代码的问题:咋一看,好像没什么问题,但深入分析,问题就出现在 Executors.newFixedThreadPool(15)这段代码上。...因为使用了 newFixedThreadPool 线程池,而它的工作机制是,固定了N个线程,而提交给线程池的任务队列是不限制大小的,如果Kafka发消息被阻塞或者变慢,那么显然队列里面的内容会越来越多,...因此若使用不当,讲很快导致内存被打满,需要谨慎啊。...在使用CachedThreadPool时,一定要注意控制任务的数量,否则,由于大量线程同时运行,很有会造成系统瘫痪。...newFixedThreadPool public static ExecutorService newFixedThreadPool(int nThreads) { return new
我们在之前的线程学习中,都是之间创建新的线程,显性线程,用的时候开启,用完销毁,效率低且不安全 而且我们看到在阿里巴巴代码规范规约中也是不建议显式创建线程,建议使用线程池。 ?...线程池使用 public static ExecutorService newFixedThreadPool(int nThreads); 得到一个线程池对象,初始化参数是要求的当前线程池中的线程数...(thread1); newFixedThreadPool.submit(thread1); // 因为原本的5个线程都在被使用中,这里需要等待5个线程执行完毕,出现空闲线程 // 来执行对应的目标代码...newFixedThreadPool.submit(thread1); newFixedThreadPool.submit(thread1); newFixedThreadPool.submit...关闭线程池 // 一般不用关闭线程池,会随着程序的退出而关闭 newFixedThreadPool.shutdown(); } } ps:匿名内部类的使用虽说很香,但是还不够香,下边我们就要从匿名内部类引出
12.线程池 线程池 背景:经常创建和销毁、使用量特别大的资源,比如并发情况下的线程,对性能影响很大。 思路:提前创建好多个线程,放入线程池中,使用时直接获取,使用完放回池中。...代码示例 1.创建一个可重用固定线程数的线程池 Executors.newFixedThreadPool(n) //1.创建一个可重用固定线程数的线程池 Executors.newFixedThreadPool...(n) ExecutorService pool = Executors.newFixedThreadPool(5); 2.使用 Callable 接口创建一个匿名线程,并且使用线程池的线程启动 @Test...(n) ExecutorService pool = Executors.newFixedThreadPool(5); //2.使用 Callable 接口创建一个匿名线程,并且使用线程池的线程启动...Executors.newFixedThreadPool(n) ExecutorService pool = Executors.newFixedThreadPool(5); //2
newFixedThreadPool线程池常用使用方式如下: public static void main(String[] args) { ExecutorService fixedThreadPool...需要注意的是,newFixedThreadPool线程池使用的队列也是无界队列LinkedBlockingQueue,源码如下: public static ExecutorService newFixedThreadPool...在使用newFixedThreadPool线程池的时候,也要评估访问量峰值来设置活跃线程的大小,另外在互联网行业,流量变化的不可预知性太强,所以不建议使用默认的方式创建newFixedThreadPool...与其他等价的{@code newFixedThreadPool(1)}不同,返回的执行器保证不会重新配置来使用其他线程。...,此处使用的是默认线程工厂Executors.defaultThreadFactory() 7)handler:当线程池无法处理新提交的任务时的拒绝策略,此处使用默认的AbortPolicy newFixedThreadPool
https://cloud.tencent.com/developer/user/1148436/activities 这里主要使用Executors中的4种静态创建线程池实例方法中的 newFixedThreadPool...public static ExecutorService newFixedThreadPool(int nThreads); public static ExecutorService newFixedThreadPool...线程池一般的使用方法: 通过 Executors.newFixedThreadPool(...).execute(Runnable()) 并发运行,例如下面的代码片段 1 ExecutorService...线程池和AsyncTask()结合使用: AsyncTask() 知识恶补入口:http://www.2cto.com/kf/201203/122729.html 这里只说下 AsyncTask()的executeOnExecutor...public static int j = 0 ; 20 public final Object myTPLock = new Object();//对象锁,主要用来实现同步,我这里并没有使用
Executors创建线程池方式有如下几种: Executors.newFixedThreadPool(10);//LinkedBlockingQueue 无限加入队列 Executors.newScheduledThreadPool...//newFixedThreadPool创建线程池源码 public static ExecutorService newFixedThreadPool(int nThreads) { /**...和SingleThreadExecutor类似,唯一的区别就是核心线程数不同,并且由于使用的是LinkedBlockingQueue。...默认的最大任务数量是Integer.MAX_VALUE,非常大,可以理解为无限大吧;但是存在这种情况,当每个线程获取到一个任务后,执行时间比较长,导致workQueue里积压的任务越来越多,机器的内存使用不停的飙升...一个由数组结构组成的有界阻塞队列 LinkedBlockingQueue:一个由链表结构组成的有界阻塞队列 PriorityBlockingQueue:一个支持优先级排序的无界阻塞队列 DelayQueue:一个使用优先级队列实现的无界阻塞队列
--------newFixedThreadPool (创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。)...public static ExecutorService newFixedThreadPool (int nThreads); public static ExecutorService newFixedThreadPool...线程池一般的使用方法: 通过 Executors.newFixedThreadPool(...).execute(Runnable()) 并发运行,例如下面的代码片段 1 ExecutorService...线程池和AsyncTask()结合使用: AsyncTask() 知识恶补入口:http://www.2cto.com/kf/201203/122729.html 这里只说下 AsyncTask()的executeOnExecutor...public static int j = 0 ; 20 public final Object myTPLock = new Object();//对象锁,主要用来实现同步,我这里并没有使用
AtomicReference("initial"); int numberOfThreads = 10; ExecutorService executor = Executors.newFixedThreadPool...AtomicReference(0); int numberOfThreads = 10; ExecutorService executor = Executors.newFixedThreadPool...AtomicReference(0); int numberOfThreads = 10; ExecutorService executor = Executors.newFixedThreadPool...AtomicReference(0); int numberOfThreads = 10; ExecutorService executor = Executors.newFixedThreadPool...new AtomicReference(0); // compareAndSet ExecutorService executorCAS = Executors.newFixedThreadPool
从匿名内部类引入Lambda表达式 在线程池那篇博客中,我们通过使用匿名内部类来作为参数传入submit方法中。 ?...= Executors.newFixedThreadPool(5); newFixedThreadPool.submit(new Runnable() { @Override...cook Cook接口的实现类对象 */ public static void invokeCook(Cook cook) { cook.cooking(); } } Lambda表达式使用...有且只有一个缺省属性为public abstract方法的接口,例如 Comparator接口,Runnable接口 使用lambda表达式是有一个前后要求约束的方法的参数为接口类型,或者说局部变量使用调用方法...,可以使用lambda也OK 有且只有一个抽象方法的接口,称之为【函数式接口】Comparator接口,Runnable接口
目录 一、线程池的作用 二、线程池的关系图 三、线程池的创建及参数 四、线程池的使用原理 五、线程池的使用 一、线程池的作用 随着cpu核数越来越多,不可避免的利用多线程技术以充分利用其计算能力。...线程的创建和销毁,都涉及到系统调用,比较消耗系统资源,所以就引入了线程池技术,线程池中有已经创建好的线程,可直接使用,并且使用完了,直接再次放回线程池,避免频繁的线程创建和销毁。...ForkJoinPool是Fork/Join框架下使用的一个线程池,一般情况下,我们使用的比较多的就是ThreadPoolExecutor。...()——创建一个单线程的线程池 2、newFixedThreadPool(int n)——创建一个固定大小的线程池 3、newCachedThreadPool()——创建一个可缓存的线程池 4、newScheduledThreadPool...()固定线程数的线程池 public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor
线程池 JDK1.5之后,实现了线程池程序; java.util.concurrent 类Executors:工厂类,创建线程池工厂; (方法)static ExecutorService newFixedThreadPool...返回值为线程池对象; 步骤: 1、创建线程池对象; 2、创建Runnable接口子类对象; 3、提交Runnable接口子类对象; 测试类 ExecutorService es = Executors.newFixedThreadPool...System.out.println(Thread.currentThread().getName()+"的方法"); } } 执行结果 ExecutorService es = Executors.newFixedThreadPool...(2);//创建线程池 es.shutdown();//停止线程池 创建线程的方式③(实现Callable接口) 实现步骤: 1、工厂类Executors静态方法newFixedThreadPool...提交线程任务; Future submit(Callable c) Future的get()方法获取线程任务的返回值 测试类 ExecutorService es = Executors.newFixedThreadPool
简介 在java中,除了单个使用Thread之外,我们还会使用到ThreadPool来构建线程池,那么在使用线程池的过程中需要注意哪些事情呢? 一起来看看吧。...Executors.newFixedThreadPool(int nThreads) ,创建一个可重用固定线程数的线程池。这个线程池里最多包含nThread个线程。...第二种方法就是使用UncaughtExceptionHandler。...但是ExecutorService执行的是一个个的Runnable,怎么使用ExecutorService来提交Thread呢?...正确的使用方法就是在线程每次执行完任务之后,都去调用一下ThreadLocal的remove操作。
文章目录 前言 一、ThreadPoolExecutor 构造参数 二、newCachedThreadPool 参数分析 三、newFixedThreadPool 参数分析 四、newSingleThreadExecutor...参数分析 前言 在上一篇博客 【Java 并发编程】线程池机制 ( 线程池示例 | newCachedThreadPool | newFixedThreadPool | newSingleThreadExecutor...) 使用了 3 种类型的线程池 , 3 种线程池都使用了 ThreadPoolExecutor , 该类时线程池的核心 ; 本篇博客中分析这 3 种线程池 ; 一、ThreadPoolExecutor...参数分析 ---- ExecutorService executorService2 = Executors.newFixedThreadPool(10); 创建线程池代码如下 : public...static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads
但是我要先提醒一下,不建议使用 Executors 创建线程。...面试官:那你能介绍一下 newFixedThreadPool 的使用方法吗? 派大星:当然可以。...newFixedThreadPool 可以创建一个固定大小的线程池,可控制并发的线程数,超出的线程会在队列中等待。...而 newFixedThreadPool 可以限制线程的数量,避免线程数过多,但是如果任务数量过多,会导致任务在队列中等待,从而导致响应时间变慢。 面试官:那你建议我们使用哪种创建方式呢?...派大星:我建议使用 ThreadPoolExecutorPools 创建方式进行自定义配置。
线程池 线程池的概述 程序启动一个新线程成本是比较高的,因为它涉及到要与操作系统进行交互.而使用线程池可以很好的提高性能,尤其是当程序中要创建大量生存期很短的线程时,更应该考虑使用线程池.线程池里的每一个线程代码结束后...,并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个对象来使用.在JDK5之前,我们必须手动实现自己的线程池,从JDK5开始,java内置支持线程池 内置线程池的使用步骤 创建线程池对象 创建Runnable...实例 提交Runnable实例 关闭线程池 // public static ExecutorService newFixedThreadPool(int nThreads) ExecutorService...pool = Executors.newFixedThreadPool(2); // 可以执行Runnable对象或者Callable对象代表的线程 pool.submit(new MyRunnable...MyRunnable()); //结束线程池 pool.shutdown(); 多线程程序实现的方式3 // 创建线程池对象 ExecutorService pool = Executors.newFixedThreadPool
为什么线程池不允许使用Executors去创建? Executors Executors 是一个Java中的工具类。提供工厂方法来创建不同类型的线程池。...常用方法有以下几个: //创建固定数目线程的线程池 ExecutorService executor1 = Executors.newFixedThreadPool(8); //创建一个可缓存的线程池,...终止并从缓存中移除那些已有 60 秒钟未被使用的线程。...而newFixedThreadPool中创建LinkedBlockingQueue时,并未指定容量。...创建线程池的正确姿势 避免使用Executors创建线程主要是避免其中一些参数给的默认值,那么可以直接用ThreadPoolExecutor创建线程,并且指定具体的参数值。
领取专属 10元无门槛券
手把手带您无忧上云