首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

深入理解 Java 线程池

一、简介 什么是线程池 线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后创建线程自动启动这些任务。...: schedule 方法可以指定延时执行一个 Runnable 或者 Callable 任务。...此队列是基于数组先进先出队列(FIFO)。 此队列创建时必须指定大小。 LinkedBlockingQueue - 无界阻塞队列。 此队列是基于链表先进先出队列(FIFO)。...每次提交一个任务就会新创建一个工作线程,如果工作线程数量达到线程池最大线程数,则将提交任务存入到阻塞队列中。...终止,如果你又提交了新任务,则线程池重新创建一个工作线程。 此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说 JVM)能够创建最大线程大小

47530

Java并发学习之玩转线程池

(注意线程池阻塞队列可以不设置长度) 2....学术说明 来自百科解释: 线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后创建线程自动启动这些任务。线程池线程都是后台线程。...至于我们应该调用哪一种方法来关闭线程池,应该由提交到线程池任务特性决定,通常调用shutdown来关闭线程池,如果任务不一定要执行完,则可以调用shutdownNow ---- 2....这个时候新任务C,会挂在阻塞队列中,知道线程池中某个任务执行完毕,释放资源之后,任务C才会执行 简单来说,这个固定大小线程池,就是线程池中任务恒定为指定个数(即便空闲,也会有这么几个线程);其他任务都放在阻塞队列中执行...那么这儿有什么用 固定大小线程池,保证同一时刻,最多只有n个任务执行,所以可以有效控制并发数 java.util.concurrent.Executors#newSingleThreadExecutor

66860
您找到你想要的搜索结果了吗?
是的
没有找到

Java并发系列】线程池

当Worker对应线程池启动时,它会执行线程池中任务;当执行完一个任务,它会从线程池阻塞队列中取出一个阻塞任务来继续运行。...该线程池中线程数量始终不变,当有新任务提交时,线程池中有空闲线程则会立即执行,如果没有,则会暂存到阻塞队列。对于固定大小线程池,不存在线程数量变化。...没有任务执行时,当线程空闲时间超过keepAliveTime(60秒),则工作线程将会终止被回收,当提交新任务时,如果没有空闲线程,则创建新线程执行任务,会导致一定系统开销。...Java并发包里可阻塞方法都同时定义了限时方式和不限时方式。...使用有界队列是,需要选择合适拒绝策略,队列大小和线程池大小必须一起调节。

50120

【JUC基础】12. 线程池(一)

当maximumPoolSize数量大于corePoolSize时,多那部分空闲状态下线程,会再超过一定时间被销毁,只保留corePoolSize核心线程数。...当线程池中线程数量达到corePoolSize时,且都处于运行状态,这时候后续提交线程任务会进入到缓存阻塞队列中,等待执行。这个缓存阻塞队列也就是workQueue。...JUC中提供BlockingQueue有以下几种: ArrayBlockingQueue:由数组实现有界阻塞队列。需要指定队列容量大小。当队列已满时,添加任务操作将被阻塞,直到队列中有空位。...ArrayBlockingQueue适用于固定大小线程池,可以控制线程池中最大任务数。 LinkedBlockingQueue:由链表实现可选有界或无界阻塞队列。...如果创建LinkedBlockingQueue时没有指定容量大小,那么它将是一个无界队列,可以无限制地添加任务。如果指定了容量大小,它将成为一个有界队列。当队列已满时,添加任务操作将被阻塞

14710

由浅入深理解Java线程池及线程池的如何使用

该线程池中线程数量始终不变,当有新任务提交时,线程池中有空闲线程则会立即执行,如果没有,则会暂存到阻塞队列。对于固定大小线程池,不存在线程数量变化。...,阻塞队列使用是LinkedBlockingQueue,若有多余任务提交到线程池中,则会被暂存到阻塞队列,待空闲时再去执行。...没有任务执行时,当线程空闲时间超过keepAliveTime(60秒),则工作线程将会终止被回收,当提交新任务时,如果没有空闲线程,则创建新线程执行任务,会导致一定系统开销。...Java并发包里可阻塞方法都同时定义了限时方式和不限时方式。...使用有界队列是,需要选择合适拒绝策略,队列大小和线程池大小必须一起调节。

7.7K111

快速掌握并发编程---线程池原理和实战

在线程池中总有那么几个活跃线程,也有一定最大值限制,一个业务使用完线程之后,不是立即销毁而是将其放入到线程池中,从而实现线程复用。...LinkedBlockingQueue 是一个由链表实现有界队列阻塞队列,但大小默认值为Integer.MAX_VALUE整形数最大值, 所以我们使用LinkedBlockingQueue时建议手动传值...,为其提供我们所需大小,避免队列过大造成机器负载或者内存爆满等情况。...SynchronousQueue 是一个没有容量,是无缓冲等待队列,是一个不存储元素阻塞队列,会直接将任务交给消费者,必须等队列添加元素被消费才能继续添加新元素。...,而使用 get(long timeout,TimeUnit unit)方法则会阻塞当前线程一段时间立即返回,这时候有可能任务没有执行完。

25210

线程池(面试常考)

认识线程池 关于“池”概念,我们接触过字符串常量池,数据库连接池,它们都被用作共享和缓存资源,通俗将就是使用时候直接从池子里拿,线程池也一样,初始化时候,就创建一定数量元素,后面需要使用线程就直接从线程池中取...表示一个线程池实例 Executors 是一个工厂类, 能够创建出几种不同风格线程池 提交任务到线程池中阻塞队列中: execute(Runnable task) submit(Runnable...//创建有固定大小线程池 ExecutorService pool2 = Executors.newFixedThreadPool(4); //创建有计划任务线程池...pool4 = Executors.newSingleThreadExecutor(); ‍️注意:这种创建方式以后工作中不建议用 在工作中要阻塞队列设置大小,如果不设置大小某个时间会导致内存不够...线程池模拟实现 前提说明: 这里阻塞队列实现采用链表方式阻塞 我们要求线程池创建时候,就创建线程不停队列中取任务来执行 这里创建5个员工 ‍️代码实现: import java.util.concurrent.BlockingDeque

20520

深入探索Java并发编程:ArrayBlockingQueue详解

一、ArrayBlockingQueue概述 ArrayBlockingQueue是一个基于数组有界阻塞队列。它在创建时需要指定队列大小,并且这个大小之后是不能改变。...这种方式可以实现任务异步执行和资源有效利用。 四、最佳实践 合理设置队列大小使用ArrayBlockingQueue时,应根据实际需求合理设置队列大小。...避免队列中存储大量数据:由于ArrayBlockingQueue是基于数组实现,每个元素都会占用一定内存空间。因此,应避免队列中存储大量数据,以减少内存消耗和垃圾回收压力。...代码中模拟一个生产者线程生产数据,多个消费者线程消费数据场景,并且消费者处理完数据后会将结果存回另一个阻塞队列中以供后续处理。...最后,我们主线程中等待生产者线程完成,关闭消费者线程ExecutorService,并处理resultQueue中剩余数据。

22710

一文读懂JDK源码:ThreadPoolExecutor

0 unit 生存时间单位时间 参考枚举类:java.util.concurrent.TimeUnit workQueue 工作线程队列 用于存放提交但是尚未被执行任务 threadFactory...,否则一直put线程会一直阻塞(内部维护了一个Transferer 抽象类,提供了公平抢占消费&非公平抢占消费实现); 超出基本大小线程资源一段时间后会被销毁,因此 keepAliveTime 设置为...总结: 好处:“无界限”线程池,可以资源被完全耗尽之前能够全力处理所有的任务提交(双刃剑); 弊端:由于最大线程池容量不设限,提交任务极其频繁条件下,可能会创建数量非常多线程,甚至OOM。...C 如果 workerCount >= corePoolSize,且线程池内阻塞队列未满(不阻塞),则将任务添加到该阻塞队列中。(基本大小满足了,还有临时工也在帮忙,再来单子得阻塞..)...所以,推荐一篇精品文章给大家自行阅读:《Java线程池实现原理及其美团业务中实践》。

30220

Java并发编程】- 02 线程池总结

; 如果等待队列已满,并且工作线程数 < maxPoolSize,则创建一个新线程来运行新任务,这个机制可能很多人都会搞错,这里就容易出现之前提交任务还在等待队列阻塞,但是新提交任务却被执行情况,千万注意...,提供了一些创建线程池方法,主要如下: ExecutorService newFixedThreadPool(int nThreads):创建一个固定大小、任务队列容量无界线程池; ExecutorService...CompletionService对ExecutorService进行包装,将结果集按照完成时间顺序放入到阻塞队列中,获取结果时只需要从阻塞队列中获取即可,即实现:先完成任务先获取结果。...,CompletionService就是重写该方法,FutureTask任务完成时添加到阻塞队列中去,这样就可以从阻塞队列中获取已完成任务,见下: protected void done() { completionQueue.add...(task); } Tips:ExecutorCompletionService类中使用LinkedBlockingQueue无界队列存储结果集,所以,一定要及时去取结果,不然完成任务结果不停堆积到阻塞队列

33810

线程池和队列学习,队列在线程池中使用,什么是队列阻塞,什么是有界队列「建议收藏」

1,按阻塞队列和非阻塞队列划分为两类 1、没有实现阻塞接口LinkedList: 实现了java.util.Queue接口和java.util.AbstractQueue接口   内置阻塞队列...收集关于队列大小信息会很慢,需要遍历队列。...使用非阻塞队列时候有一个很大问题就是:它不会对当前线程产生阻塞,那么面对类似消费者-生产者模型时,就必须额外地实现同步策略以及线程间唤醒策略,简单理解就是非阻塞队列时,一个线程去拿队列东西,发现这个队列是空...当队列中有元素,被阻塞线程会自动被唤醒(不需要我们编写代码去唤醒),也就是始终有个线程等着这个队列,如果队列中有东西了,被阻塞线程会主动去拿。这样提供了极大方便性。...3)步骤2)中新创建线程将任务执行完,会执行 SynchronousQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS)。

2.1K30

当面试官问线程池时,你应该知道些什么?

线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后创建线程自动启动这些任务。 为什么要用线程池? 降低资源消耗 通过重复利用已创建线程降低线程创建和销毁造成消耗。...默认情况下,创建了线程池,线程池中线程数为 0,当有任务来之后,就会创建一个线程去执行任务,当线程池中线程数目达到 corePoolSize ,就会把到达任务放到缓存队列当中。...workQueue:任务队列。用于保存等待执行任务阻塞队列。 可以选择以下几个阻塞队列。...使用 CachedThreadPool 时,一定要注意控制任务数量,否则,由于大量线程同时运行,很有会造成系统瘫痪。...:基于链表先进先出队列,如果创建时没有指定此队列大小,则默认为 Integer.MAX_VALUE; SynchronousQueue:这个队列比较特殊,它不会保存提交任务,而是将直接新建一个线程来执行新来任务

36730

Java】一文看懂Thread 线程池 7 种创建方式、任务队列及自定义线程池(代码示例)

最大线程数:线程池中允许最大线程数。 存活时间:非核心线程没有任务执行时存活时间。 时间单位:与存活时间配合使用时间单位。 工作队列:存储等待执行任务阻塞队列。...LinkedBlockingQueue:一个由链表结构组成有界阻塞队列。 SynchronousQueue:一个不存储元素阻塞队列,即直接提交给线程不保持它们。...DelayQueue:一个使用优先级队列实现无界阻塞队列,只有延迟期满时才能从中提取元素 LinkedTransferQueue:一个由链表结构组成无界阻塞队列。...Java线程池中,submit() 和 execute() 是两种不同方法,它们都用于向线程池提交任务。...示例代码中,我们首先使用schedule方法提交了一个延迟2秒执行单次任务。

64111

Java线程池用过吧?来说说你是怎么理解线程池吧?

而且任务队列最好也要有容量,但也应该是根据业务场景来配置容量,而且任务队列还可以定制一些规则,例如:按照一定规则出队。所以我们把任务队列也配置成参数,创建线程池时候传入。...下面说几个线程池常见考察点 Java线程池阻塞队列都有哪几种 ArrayBlockingQueue : 有界队列,按照阻塞先后顺序访问队列,默认情况下不保证线程公平访问队列~如果要保证公平性...不允许任务队列中等待时候可以使用此队列。 DelayQueue:延迟获取元素队列,按照指定时间获取,为无界阻塞队列。...PriorityBlockingQueue:优先级排序队列,按照一定优先级对任务进行排序,默认是小顶堆。 LinkedBlockingDeque:基于链表双端阻塞队列。...,并且阻塞任务队列还是一个无解队列,这样,当处理任务线程数量达到核心线程数时,再提交任务都会进行到阻塞队列里,但是阻塞队列是无界,这样就提交任务高峰期有可能会造成任务一直堆积在队列里,超出内存容量最终导致内存溢出

47030

一步一步分析RejectedExecutionException异常

异常场景2 产生RejectedExecutionException异常第二个原因: 要提交阻塞队列任务超出了该队列最大容量。...当线程池里线程都繁忙时候,新任务会被提交阻塞队列保存,这个阻塞队列一旦饱和,线程池就会拒绝接收新任务,随即抛出异常。...,运行之后抛异常 } } 在上面的例子中,我们使用了一个大小为15ArrayBlockingQueue阻塞队列来保存等待执行任务。...我们可以选择一种不需要设置大小限制数据结构,比如LinkedBlockingQueue阻塞队列。...其实我们可以给使用ArrayBlockingQueue作为阻塞队列ThreadPoolExecutor线程池提交超过15个任务,只要我们提交新任务前设置一个完成原来任务等待时间,这时3个线程就会逐渐消费

5.2K30

JUC 多线程 线程池

二、线程池体系结构及工具类 1、线程池体系结构 Java.util.concurrent.Executor : 负责线程使用与调度根接口 |-- ExecutorService...,具备两者功能 2、Executors工具类 ExecutorService new FixedThreadPool() : 创建固定大小线程池 ExecutorService newCachedThreadPool...如果允许任务丢失,这是最好一种方案。 3、以上内置拒绝策略均实现了RejectedExecutionHandler接口 五、线程池底层工作原理? 1、创建了线程池,等待提交过来任务请求。...所以线程池所有任务完成它最终会收缩到corePoolSize大小。...单线程上运行IO密集型任务会导致浪费大量CPU运算能力浪费等待。 所以IO密集型任务中使用多线程可以大大加速程序运行,即使单核CPU上,这种加速主要就是利用了被浪费掉阻塞时间。

61931

Executor框架

Java并发容器和框架 Java12个原子操作类介绍 Java并发工具类 Java线程池 Executor框架 ---- 前言 Java中,使用线程来异步执行任务。...Java线程创建与销毁需要一定开销,如果我们为每一个任务创建一个新线程来执行,这些线程创建与销毁将消耗大量计算资源。...但从API可以看到,Java仅仅保证返回是一个实现了Future接口对象。将来JDK实现中,返回可能不一定是FutureTask。...AQS是一个同步框架,它提供通用机制来原子性管理同步状态、阻塞和唤醒线程,以及维护被阻塞线程队列。...这个操作改变AQS状态,改变状态可允许一个或多个阻塞线程被解除阻塞。FutureTaskrelease操作包括run()方法和cancel(...)方法。

13810

Java】线程池梳理

每个处理器核,都有一个队列存储着需要完成任务。对于多核机器来说,当一个核对应任务处理完毕,就可以去帮助其他核处理任务。...类型对象; ArrayBlockingQueue,队列是有界,基于数组实现阻塞队列; LinkedBlockingQueue,队列可以有界,也可以无界。...基于链表实现阻塞队列; SynchronousQueue,不存储元素阻塞队列,每个插入操作必须等到另一个线程调用移除操作,否则插入操作将一直处于阻塞状态。...另外,也可以使用它重载方法get(long timeout, TimeUnit unit),这个方法也会阻塞,但是超时时间内仍然没有返回结果时,将抛出异常TimeoutException。...注意 尽量使用手动方式创建线程池,避免使用Executors工厂类; 根据场景,合理设置线程池各个参数,包括线程池数量、队列、线程工厂和拒绝策略; 调线程池submit()方法时候,一定要尽量避免任务执行异常被吞掉问题

23920

Java线程池分享

提交任务 ExecutorService:接口 继承Executor接口 增加了submit提交任务方式(有返回值) 以及关闭 操作 AbstractExecutorService实现了ExecutorService...maximumPoolSize 最大线程池大小 keepAliveTime 空闲线程存活时间 unit 空闲线程保持存活时间单位 workQueue 阻塞任务队列,当要执行任务超出corePoolSize...时,新提交任务将会进入阻塞队列(workQueue)中,等待线程调度 当阻塞队列满了以后,如果corePoolSize < maximumPoolSize ,则新提交任务会新建线程执行任务,直至线程数达到...threadPoolExecutor.shutdown(); } } 输出结果: pool-1-thread-1 main pool-1-thread-1 分析一下:因为核心线程池+ 阻塞队列大小...当提交第一个任务时,新建线程执行任务,当提交第二个任务时,由于线程池核心大小为1并且有任务执行,放入阻塞队列,当提交第三个任务,发现阻塞队列已经满了,而且线程池最大线程个数也达到了最大。

70710

Java线程池

队列满了,还有执行任务进入时策略 workQueue参数需要传入一个BlockingQueue,这是个双缓冲队列。...保证并发安全同时,提高了队列存取效率,不能传入空对象,可设置容量大小,也可以不设置容量大小,那么它容量就是Integer.MAX_VALUE。...常用几种实现类 类 说明 ArrayBlockingQueue 规定容量大小阻塞队列 LinkedBlockingQueue 既可以规定容量大小,也可以不规定阻塞队列 SynchronizedQueue...一个特殊队列,生产消费必须交替完成队列生产一个元素,必须要有进行消费,才能继续往队列内生产元素 handler拒绝策略 当线程池指定队列容量满了时,将执行哪种拒绝任务策略 策略类 说明...比如说addWorker方法,线程池执行调度等 后续有什么新理解继续补上,未完待续 关于本文出现代码示例,已提交至码云,只看文章不懂时,一定要敲代码进行理解。 我是半月,祝你幸福!

50620
领券