1.javanewcachedthreadpool线程池使用在什么情况下?源码
2.Java的并行世界-3.0 线程池与拒绝策略
3.线程池有哪些
4.线程池newCachedThreadPool
5.java常用的几种线程池实例讲解
javanewcachedthreadpool线程池使用在什么情况下?
newCachedThreadPool 是 Java 提供的线程池工具类 ExecutorService 的一个静态方法,用于构建一个可无限扩大的源码线程池。新创建的源码线程会在空闲时被回收,再次请求任务时重新创建,源码适合处理突发性的源码、不连续的源码版权交易app源码任务流。
ExecutorService 类提供了创建不同类型的源码线程池的功能,通过 Executors.newXXX 函数可以生成四种类型的源码线程池。具体类型如下:
1. FixedThreadPool:创建一个固定数量的源码线程池,可以指定线程的源码数量。每个线程在完成任务后不会自动退出,源码而是源码等待新的任务的到来。适用于任务数量较为稳定,源码对响应时间要求较高的源码场景。
2. CachedThreadPool:即 newCachedThreadPool,源码创建一个可无限扩大的线程池,动态调整线程数量以满足任务需求。空闲的线程会被回收,新请求的任务会创建新的线程来执行。适用于处理突发的、不连续的任务流,能有效利用资源。
3. SingleThreadExecutor:创建一个单线程的线程池,所有任务在同一个线程中执行,线程不会自动退出。适用于需要顺序执行的任务,确保任务的执行顺序。
4. ScheduledThreadPool:创建一个可以处理延时任务或定时任务的线程池。适合用于定时执行任务,或在特定时间间隔后执行任务的场景。
综上,全球支付系统源码newCachedThreadPool 线程池适合处理突发的、不连续的任务流,尤其在任务量动态变化、对资源利用效率有较高要求的情况下。它能够根据任务需求动态调整线程数量,避免资源浪费,同时能有效地应对任务量的突发性变化。
Java的并行世界-3.0 线程池与拒绝策略
Jdk并发相关核心类:java.util.concurrent
java.util.concurrent.Executors提供了一些静态工厂方法,用于创建不同类型的线程池,例如:
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool();
可以通过new ThreadPoolExecutor()方法手动创建线程池,该方法需要传入四个参数,分别是核心线程数、最大线程数、线程保活时间和任务队列。其中,核心线程数和最大线程数是必填参数,线程保活时间和任务队列是可选参数。
Java中的Executors共有四种创建方式,这些方式包括使用newFixedThreadPool、newCachedThreadPool、newSingleThreadExecutor和newScheduledThreadPool。在使用这些方法时,可以根据实际需求选择最适合的方式来创建线程池。无论哪种方式,线程池都可以有效地管理和控制线程,提高程序的执行效率。
新FixedThreadPool创建一个固定大小的线程池。
以下是一个Java中创建newFixedThreadPool的代码例子:
新CachedThreadPool创建一个根据需要自动扩展的线程池,线程数根据任务数量动态调整。
以下是源码熊编程爱国一个newCachedThreadPool的Java代码示例:
新SingleThreadExecutor创建一个只有一个线程的线程池。
新ScheduledThreadPool创建一个支持定时任务的线程池。
ForkJoinPool是一个用于执行分而治之任务的线程池,特别适用于递归分解的问题,例如并行归并排序、并行求和等。
ForkJoinPool forkJoinPool = new ForkJoinPool();
ForkJoinPool在java.util.concurrent包下,从Java 7开始引入,专门用于处理需要递归分解的任务。它利用工作窃取(Work-Stealing)算法来实现高效的任务调度和线程利用,能够充分利用多核处理器的优势。
ForkJoinPool的主要特点包括:
下面是一个简单的使用ForkJoinPool的示例,计算斐波那契数列的值:
虽然上面5个线程池看上去功能特点不同,但是其内部实现原理都调用了JDK的ThreadPoolExecutor线程池类。
ThreadPoolExecutor的构造函数有多个参数,允许根据实际需求配置线程池的行为,主要包括:
corePoolSize:线程池的核心线程数,即线程池中保持的最小线程数量。即使线程处于空闲状态,核心线程也不会被销毁。
maximumPoolSize:线程池的最大线程数,即线程池中允许的最大线程数量。当任务数量超过核心线程数时,线程池会根据实际情况动态地创建新的线程,但不会超过最大线程数。
keepAliveTime:非核心线程的空闲时间超过这个时间后,会被销毁,从而控制线程池的大小。时间单位可以通过指定的TimeUnit来定义。
workQueue:任务队列,用于存放等待执行的55结构源码公式任务。ThreadPoolExecutor支持多种类型的任务队列,如ArrayBlockingQueue、LinkedBlockingQueue等。
threadFactory:用于创建线程的工厂,可以自定义线程的创建方式。
handler:拒绝策略,当线程池和队列都满了,无法继续接受新的任务时,会触发拒绝策略来处理新的任务。常见的拒绝策略包括AbortPolicy(默认策略,直接抛出异常)、CallerRunsPolicy(由调用线程来执行被拒绝的任务)、DiscardPolicy(丢弃被拒绝的任务)、DiscardOldestPolicy(丢弃队列中最老的任务)。
ThreadPoolExecutor提供了submit()和execute()等方法来向线程池提交任务,其中:
submit()方法可以接受Callable和Runnable类型的任务,并返回一个Future对象,通过这个对象可以获取任务的执行结果或者取消任务。
execute()方法只能接受Runnable类型的任务,无法获取任务的返回结果。
ThreadPoolExecutor还提供了一些方法来管理和监控线程池的状态,如getActiveCount()、getCompletedTaskCount()、getTaskCount()等。
workQueue:任务队列,其中的任务是被提交但尚未执行的任务。其类型是:BlockingQueue接口,只能用于存放Runable对象。
有界队列可以通过ArrayBlockingQueue实现,当有新任务到来时,看软件的源码如果线程池的实际线程数量小于corePoolSize,则会优先创建新的线程;如果大于corePoolSize,则会将新任务加入等待队列;若队列已满,无法加入,则在总线程数量不大于maximumPoolSize的前提下,创建新的线程执行任务;若大于maximumPoolSize,则执行拒绝策略。
无界队列可以通过LinkedBlockingQueue实现,与有界队列相比,除非系统资源耗尽,不然当有新的任务到来,并且线程数量小于corePoolSize时,线程池就会创建新的线程执行任务。但当线程数量大于corePoolSize后,就不会继续创建了。若还有任务进来,系统CPU没那么忙,还有线程资源,则任务直接进入队列等待。
优先任务队列可以通过PriorityBlockingQueue实现,可以根据任务的优先级执行任务,这是一种特殊的无界队列。
有界队列和无界队列需要做demo测试。新CachedThreadPool内部使用的是SynchronousQueue队列,这是一个直接提交队列,系统会增加新的线程执行任务,当任务执行完毕后,线程会被回收;如果开启大量任务提交,每个任务执行慢,系统会开启等量的线程处理,直到系统资源耗尽。
ThreadPoolExecutor的核心调度代码包括workerCountOf(c)来获取当前工作线程池的总数,addWorker(command)用于提交任务或创建线程池,以及reject(command)来执行拒绝策略。
Handler是RejectedExecutionHandler接口类型,代表了不同的拒绝策略。常见的拒绝策略包括:
CallerRunsPolicy:如果线程池未关闭,会直接在调用者当前线程执行等待队列放不下的任务。
AbortPolicy:会直接抛出异常,阻止系统正常运行。
DiscardPolicy:直接丢失无法放入等待队列的任务,不做异常抛出。
DiscardOldestPolicy:丢弃最老的一个请求,然后尝试把当前请求任务加入到等待队列。
注意:在创建ThreadPoolExecutor时需要指定拒绝策略,如果以上拒绝策略无法满足,可以继承RejectedExecutionHandler接口来实现自定义的拒绝策略。
最常用的是升级DiscardPolicy策略,但需要在放弃前记录请求;示例如下:
以下是RejectedExecutionHandler接口代码,可以重新实现该方法以满足自定义需求。
熟悉拒绝策略后,在线程池中还有重要参数ThreadFactory,用于控制线程的创建。通过ThreadFactory,可以实现以下功能:
命名线程:通过为线程指定有意义的名称,便于跟踪日志和调试信息。
设置线程属性:根据需要设置线程的优先级、守护状态、异常处理器等。
定制化线程创建逻辑:添加自定义逻辑来创建线程,如记录线程的创建次数、设置线程组等。
以下是简单的ThreadFactory示例:
线程池有哪些
线程池的种类: 一、固定大小线程池(Fixed Thread Pool) 固定大小线程池是一种线程数量不变的线程池。它创建指定数量的线程,这些线程在线程池中保持等待状态,处理新提交的任务。这种线程池适用于可以预测任务到达速率和离开速率的环境。Java中的`ThreadPoolExecutor`就是一种固定大小的线程池实现。 二、可缓存线程池(Cached Thread Pool) 可缓存线程池是一种根据任务数量动态调整线程数量的线程池。当有新任务提交时,如果线程池中没有空闲线程,则创建新线程处理任务;当空闲线程数量大于一定数值时,会回收闲置线程。这种线程池适用于任务到达率不稳定的情况。Java中的`Executors.newCachedThreadPool()`方法用于创建可缓存线程池。 三. 单线程化线程池(Single Thread Executor) 单线程化线程池是一种特殊的线程池,它保证所有任务在一个单独的线程中按顺序执行。这个模型在处理任务安全性较高、需要按照特定顺序执行的任务时非常有用。在Java中,可以使用`Executors.newSingleThreadExecutor()`方法来创建单线程化线程池。在这种模式下,任务同步执行不会导致并发问题,因此不需要额外的同步机制。 四、定时线程池(Scheduled ThreadPool) 定时线程池是一种可以在给定延迟后运行命令或定期执行命令的线程池。这种线程池主要用于执行定时任务和周期性任务。Java中的`ScheduledThreadPoolExecutor`类提供了定时功能,允许用户设置一次性的延迟任务或者周期性的任务执行。这种线程池适用于需要定时执行某些操作的应用场景。线程池newCachedThreadPool
新线程池newCachedThreadPool的源码揭示了其独特设计和功能。它的核心特点在于动态创建和重用线程,以提高执行短暂异步任务的程序性能。此池允许在先前构造的线程可用时重复使用它们,且最大线程数为Integer.MAX_VALUE,意味着资源使用相对灵活。
在newCachedThreadPool中,线程的存活时间设置为秒,超过此时间未使用的线程将被终止并从池中移除。这一特性有助于避免资源浪费,保持空闲时间足够长的池不会消耗任何资源。此外,新线程池不包含核心线程,其操作基于SynchronousQueue队列,确保线程间高效同步。
使用newCachedThreadPool时,程序执行到大约秒后自动终止,因为线程池已完成所有任务。存活线程在超过秒的闲置后被终止和移除,这体现了其设计原理。
为何newCachedThreadPool选择SynchronousQueue而不是其他线程池通常采用的LinkedBlockQueue?SynchronousQueue是一个特殊的阻塞队列,旨在实现线程间高效同步。它没有内部容量,且插入操作需等待相应的删除操作。此特性使其成为切换设计的理想选择,允许线程在需要时安全地传递信息、事件或任务,尤其适用于需要多线程间同步的应用场景。
SynchronousQueue通过实现Collection和Iterator接口支持所有可选方法,包括支持可选的公平性策略。默认情况下,不保证生产者和使用者线程的FIFO顺序访问,但通过将公平性策略设置为true,可以确保按此顺序授予访问权限。
总之,newCachedThreadPool通过动态线程重用和SynchronousQueue的高效同步机制,提供了一种灵活且高效的处理短暂异步任务的方法。其设计旨在优化资源使用,通过在任务完成后的秒内自动清理资源,保持系统性能高效。
java常用的几种线程池实例讲解
下面给你介绍4种线程池:1、newCachedThreadPool:
底层:返回ThreadPoolExecutor实例,corePoolSize为0;maximumPoolSize为Integer.MAX_VALUE;keepAliveTime为L;unit为TimeUnit.SECONDS;workQueue为SynchronousQueue(同步队列)
通俗:当有新任务到来,则插入到SynchronousQueue中,由于SynchronousQueue是同步队列,因此会在池中寻找可用线程来执行,若有可以线程则执行,若没有可用线程则创建一个线程来执行该任务;若池中线程空闲时间超过指定大小,则该线程会被销毁。
适用:执行很多短期异步的小程序或者负载较轻的服务器
2、newFixedThreadPool:
底层:返回ThreadPoolExecutor实例,接收参数为所设定线程数量nThread,corePoolSize为nThread,maximumPoolSize为nThread;keepAliveTime为0L(不限时);unit为:TimeUnit.MILLISECONDS;WorkQueue为:new LinkedBlockingQueue<Runnable>() 无解阻塞队列通俗:创建可容纳固定数量线程的池子,每隔线程的存活时间是无限的,当池子满了就不在添加线程了;如果池中的所有线程均在繁忙状态,对于新任务会进入阻塞队列中(无界的阻塞队列)
适用:执行长期的任务,性能好很多
3、newSingleThreadExecutor
底层:FinalizableDelegatedExecutorService包装的ThreadPoolExecutor实例,corePoolSize为1;maximumPoolSize为1;keepAliveTime为0L;unit为:TimeUnit.MILLISECONDS;workQueue为:new LinkedBlockingQueue<Runnable>() 无解阻塞队列
通俗:创建只有一个线程的线程池,且线程的存活时间是无限的;当该线程正繁忙时,对于新任务会进入阻塞队列中(无界的阻塞队列)
适用:一个任务一个任务执行的场景
4、NewScheduledThreadPool:
底层:创建ScheduledThreadPoolExecutor实例,corePoolSize为传递来的参数,maximumPoolSize为Integer.MAX_VALUE;keepAliveTime为0;unit为:TimeUnit.NANOSECONDS;workQueue为:new DelayedWorkQueue() 一个按超时时间升序排序的队列
通俗:创建一个固定大小的线程池,线程池内线程存活时间无限制,线程池可以支持定时及周期性任务执行,如果所有线程均处于繁忙状态,对于新任务会进入DelayedWorkQueue队列中,这是一种按照超时时间排序的队列结构
适用:周期性执行任务的场景
最后给你说一下线程池任务执行流程:
当线程池小于corePoolSize时,新提交任务将创建一个新线程执行任务,即使此时线程池中存在空闲线程。
当线程池达到corePoolSize时,新提交任务将被放入workQueue中,等待线程池中任务调度执行
当workQueue已满,且maximumPoolSize>corePoolSize时,新提交任务会创建新线程执行任务
当提交任务数超过maximumPoolSize时,新提交任务由RejectedExecutionHandler处理
当线程池中超过corePoolSize线程,空闲时间达到keepAliveTime时,关闭空闲线程
当设置allowCoreThreadTimeOut(true)时,线程池中corePoolSize线程空闲时间达到keepAliveTime也将关闭