优秀的手机游戏下载!
首页 ThreadPoolExcutor用法详解

ThreadPoolExcutor用法详解

发布时间:2024-01-11 00:20:34 编辑:打包星星 浏览:277

java线程池用法举例:

1、ThreadPoolExecutor executor =new ThreadPoolExecutor(2,10,30, TimeUnit.SECONDS,new ArrayBlockingQueue&lt&gt(100))

2、ThreadPoolExecutor executor2 =new ThreadPoolExecutor(2,10,30, TimeUnit.SECONDS,new LinkedBlockingDeque&lt&gt())

知道了各个参数的作用后,我们开始构造符合我们期待的线程池。首先看JDK给我们预定义的几种线程池:

一、预定义线程池

FixedThreadPool

publicstaticExecutorServicenewFixedThreadPool(intnThreads){returnnewThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,newLinkedBlockingQueue())    }

corePoolSize与maximumPoolSize相等,即其线程全为核心线程,是一个固定大小的线程池,是其优势;

keepAliveTime = 0 该参数默认对核心线程无效,而FixedThreadPool全部为核心线程;

workQueue 为LinkedBlockingQueue(无界阻塞队列),队列最大值为Integer.MAX_VALUE。如果任务提交速度持续大余任务处理速度,会造成队列大量阻塞。因为队列很大,很有可能在拒绝策略前,内存溢出。是其劣势;

FixedThreadPool的任务执行是无序的;

适用场景:可用于Web服务瞬时削峰,但需注意长时间持续高峰情况造成的队列阻塞。

CachedThreadPool

publicstaticExecutorServicenewCachedThreadPool(){returnnewThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,newSynchronousQueue())    }

corePoolSize = 0,maximumPoolSize = Integer.MAX_VALUE,即线程数量几乎无限制;

keepAliveTime = 60s,线程空闲60s后自动结束。

workQueue 为 SynchronousQueue 同步队列,这个队列类似于一个接力棒,入队出队必须同时传递,因为CachedThreadPool线程创建无限制,不会有队列等待,所以使用SynchronousQueue;

适用场景:快速处理大量耗时较短的任务,如Netty的NIO接受请求时,可使用CachedThreadPool。

SingleThreadExecutor

publicstaticExecutorServicenewSingleThreadExecutor(){returnnewFinalizableDelegatedExecutorService            (newThreadPoolExecutor(1,1,0L, TimeUnit.MILLISECONDS,newLinkedBlockingQueue()))    }

咋一瞅,不就是newFixedThreadPool(1)吗?定眼一看,这里多了一层FinalizableDelegatedExecutorService包装,这一层有什么用呢,写个dome来解释一下:

publicstaticvoidmain(String[] args){        ExecutorService fixedExecutorService = Executors.newFixedThreadPool(1)        ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) fixedExecutorService        System.out.println(threadPoolExecutor.getMaximumPoolSize())        threadPoolExecutor.setCorePoolSize(8)                ExecutorService singleExecutorService = Executors.newSingleThreadExecutor()//      运行时异常 java.lang.ClassCastException//      ThreadPoolExecutor threadPoolExecutor2 = (ThreadPoolExecutor) singleExecutorService}

对比可以看出,FixedThreadPool可以向下转型为ThreadPoolExecutor,并对其线程池进行配置,而SingleThreadExecutor被包装后,无法成功向下转型。 因此,SingleThreadExecutor被定以后,无法修改,做到了真正的Single。

ScheduledThreadPool

publicstaticScheduledExecutorServicenewScheduledThreadPool(intcorePoolSize){returnnewScheduledThreadPoolExecutor(corePoolSize)    }

newScheduledThreadPool调用的是ScheduledThreadPoolExecutor的构造方法,而ScheduledThreadPoolExecutor继承了ThreadPoolExecutor,构造是还是调用了其父类的构造方法。

publicScheduledThreadPoolExecutor(intcorePoolSize){super(corePoolSize, Integer.MAX_VALUE,0, NANOSECONDS,newDelayedWorkQueue())    }

二、自定义线程池

线程池之ThreadPoolExecutor使用

当我们需要实现并发、异步等操作时,可以使用ThreadPoolExecutor。

ThreadPoolExecutor

线程池:

系统中,我们创建(extend Thread/implement Runnable)、销毁(正常run方法完成后线程终止)线程的代价是比较高昂的。

如果频繁地创建和销毁进程,会大大降低系统运行效率和吞吐量。

线程池使得线程可以被复用,避免了线程频繁创建和销毁的开销,提高系统的运行效率和吞吐量。

实例

ThreadPoolExecutor.execute(new Runnable () {})

相关概念:

Task任务:new Runnable () {}

任务就是一个Runnable的对象,任务的执行方法就是该对象的run方法。

缓冲队列:workQueue

一个阻塞队列。

BlockingQueue&ltRunnable&gtworkQueue

ThreadPoolExcutor用法详解

corePoolSize:核心线程数

核心线程会一直存活,即使没有任务需要执行。

当线程数小于核心线程数时(还未满,就会一直增),即使有线程空闲,线程池也会优先创建新线程处理。

maxPoolSize:最大线程数

当线程数大于corePoolSize,且任务队列已满时。线程池会创建新线程来处理任务,直到线程数量达到maxPoolSize。

execute(Runnable)

通过execute将一个任务交由线程池管理。

当一个任务通过execute方法欲添加到线程池时,线程池采用的策略如下(即添加任务的策略):

1、如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。

2、如果此时线程池中的数量等于corePoolSize,但是缓冲队列workQueue未满,那么任务被放入缓冲队列。

3、如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理被添加的任务。

4、如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过handler所指定的策略来处理此任务。

如下图:

希望对您有所帮助!~

ThreadPoolExecutor提供了四个构造方法:

我们以最后一个构造方法(参数最多的那个),对其参数进行解释:

如果对这些参数作用有疑惑的请看 ThreadPoolExecutor概述 。

知道了各个参数的作用后,我们开始构造符合我们期待的线程池。首先看JDK给我们预定义的几种线程池:

适用场景:可用于Web服务瞬时削峰,但需注意长时间持续高峰情况造成的队列阻塞。

适用场景:快速处理大量耗时较短的任务,如Netty的NIO接受请求时,可使用CachedThreadPool。

咋一瞅,不就是newFixedThreadPool(1)吗?定眼一看,这里多了一层FinalizableDelegatedExecutorService包装,这一层有什么用呢,写个dome来解释一下:

对比可以看出,FixedThreadPool可以向下转型为ThreadPoolExecutor,并对其线程池进行配置,而SingleThreadExecutor被包装后,无法成功向下转型。 因此,SingleThreadExecutor被定以后,无法修改,做到了真正的Single。

newScheduledThreadPool调用的是ScheduledThreadPoolExecutor的构造方法,而ScheduledThreadPoolExecutor继承了ThreadPoolExecutor,构造是还是调用了其父类的构造方法。

对于ScheduledThreadPool本文不做描述,其特性请关注后续篇章。

以下是自定义线程池,使用了有界队列,自定义ThreadFactory和拒绝策略的demo:

输出结果如下:

其中线程线程1-4先占满了核心线程和最大线程数量,然后4、5线程进入等待队列,7-10线程被直接忽略拒绝执行,等1-4线程中有线程执行完后通知4、5线程继续执行。

多线程系列目录(不断更新中):

线程启动原理

线程中断机制

多线程实现方式

FutureTask实现原理

线程池之ThreadPoolExecutor概述

线程池之ThreadPoolExecutor使用

线程池之ThreadPoolExecutor状态控制

线程池之ThreadPoolExecutor执行原理

线程池之ScheduledThreadPoolExecutor概述

线程池的优雅关闭实践

以上就是关于ThreadPoolExcutor用法详解全部的内容,如果了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

更多相关资讯

java线程池用法举例: 1、ThreadPoolExecutor executor =new ThreadPoolExecutor(2,10,30, Time…
查看详情
java线程池用法举例: 1、ThreadPoolExecutor executor =new ThreadPoolExecutor(2,10,30, Time…
查看详情
java线程池用法举例: 1、ThreadPoolExecutor executor =new ThreadPoolExecutor(2,10,30, Time…
查看详情
相关资讯
猜你喜欢