我是靠谱客的博主 激昂铃铛,这篇文章主要介绍线程池使用详解,现在分享给大家,希望可以做个参考。

目录

原理

好处

创建线程池

构造方法

参数详解

int corePoolSize

int maximumPoolSize

long keepAliveTime

TimeUnit unit

BlockingQueue workQueue

ThreadFactory threadFactory

RejectedExecutionHandler hanler

执行任务

execute()

submit()

并发操作

关闭线程池

shutdown()

shutdownNow()


原理

线程池就是一个存放已经创建好的线程的池子,当有任务提交给线程池执行时,线程池中的某个线程会主动执行该任务。如果线程池中的线程数量不够应付数量众多的任务时,需要自动扩充新的线程到线程池中,数量是有限的。当任务比较少的时候,线程池中的线程能够自动回收,释放资源。

好处

降低资源消耗:通过重复利用已创建的线程降低线程创建和销毁造成的消耗。

提高响应速度:当任务到达时,任务可以不需要等到线程创建就能立即执行。

提高线程的可管理性:线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一分配、调优和监控。

创建线程池

通过java.util.concurrent.ThreadPoolExecutor来创建一个线程池。

构造方法

//五个参数的构造函数

public ThreadPoolExecutor(int corePoolSize,

                          int maximumPoolSize,

                          long keepAliveTime,

                          TimeUnit unit,

                          BlockingQueue<Runnable> workQueue)

 

//六个参数的构造函数-1

public ThreadPoolExecutor(int corePoolSize,

                          int maximumPoolSize,

                          long keepAliveTime,

                          TimeUnit unit,

                          BlockingQueue<Runnable> workQueue,

                          ThreadFactory threadFactory)

 

//六个参数的构造函数-2

public ThreadPoolExecutor(int corePoolSize,

                          int maximumPoolSize,

                          long keepAliveTime,

                          TimeUnit unit,

                          BlockingQueue<Runnable> workQueue,

                          RejectedExecutionHandler handler)

 

//七个参数的构造函数

public ThreadPoolExecutor(int corePoolSize,

                          int maximumPoolSize,

                          long keepAliveTime,

                          TimeUnit unit,

                          BlockingQueue<Runnable> workQueue,

                          ThreadFactory threadFactory,

                          RejectedExecutionHandler handler)

参数详解

int corePoolSize

该线程池中核心线程的最大数量,即默认情况下一直会存活在线程池中,即使处于闲置状态。如果当前线程总数小于corePoolSize,新建的线程是核心线程,否则是非核心线程。

int maximumPoolSize

该线程池中线程总数最大值。

long keepAliveTime

表示线程没有任务执行时最多保持多久时间会终止。默认情况下,只有当线程池中的线程数大于corePoolSize时,keepAliveTime才会起作用,即当线程池中的线程数大于corePoolSize时,如果一个线程空闲的时间达到keepAliveTime,则会终止,直到线程池中的线程数不超过corePoolSize。但是如果调用了allowCoreThreadTimeOut(boolean)方法,在线程池中的线程数不大于corePoolSize时,keepAliveTime参数也会起作用,直到线程池中的线程数为0。

TimeUnit unit

参数keepAliveTime的时间单位

TimeUnit是一个枚举类型,其包括:
NANOSECONDS : 1微毫秒 = 1微秒 / 1000
MICROSECONDS : 1微秒 = 1毫秒 / 1000
MILLISECONDS : 1毫秒 = 1秒 /1000
SECONDS : 秒
MINUTES : 分
HOURS : 小时
DAYS : 天

BlockingQueue<Runnable> workQueue

该线程池中的任务队列,用来存储等待执行的任务。

ThreadFactory threadFactory

线程工厂,主要用来创建线程,一般用不上。

RejectedExecutionHandler hanler

表示当拒绝处理任务时的策略,有以下四种取值:

 

ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。

ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。

ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)

ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务

执行任务

execute()

这个方法是顶层接口Executor中声明的方法,在ThreadPoolExecutor类中进行了具体实现,参数是Runnable,通过这个方法可以向线程池提交一个任务,交由线程池去执行。

submit()

Submit是在接口ExecutorService中声明的方法,在ThreadPoolExecutor类的抽象父类AbstractExecutorService中进行了具体实现。这个方法也是用来向线程池提交任务的,参数是Runnable,但是它和execute()方法不同,它能够返回任务执行的结果,去看submit()方法的实现,会发现它实际上还是调用的execute()方法,只不过它利用了Future来获取任务执行结果。

并发操作

可以和CountDownLatch配合使用:

1、主线程使用await() 阻塞住,直到所有子线程都执行完毕了,才会继续向下执行。

2、所有子线程共享同一个 CountDownLatch变量,需要执行的线程总数。

3、所有子线程的finally块中,必须要countDown() ,确保 "无论 正确、异常 都会countDown",否则主线程会由于"某一个 子任务 没有countDown过,就执行结束了,导致CountDownLatch最终无法被countDown 到 0 ,而被永远挂住。

关闭线程池

shutdown()

不会立即终止线程池,而是要等所有任务缓存队列中的任务都执行完后才终止,但再也不会接受新的任务。

shutdownNow()

立即终止线程池,并尝试打断正在执行的任务,并且清空任务缓存队列,返回尚未执行的任务。

最后

以上就是激昂铃铛最近收集整理的关于线程池使用详解的全部内容,更多相关线程池使用详解内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(61)

评论列表共有 0 条评论

立即
投稿
返回
顶部