我是靠谱客的博主 轻松自行车,这篇文章主要介绍Java线程池创建详解,现在分享给大家,希望可以做个参考。

线程池

复制代码
1
2
3
4
5
6
7
8
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
  • corePoolSize 核心线程数
  • maximumPoolSize 最大线程数量(核心线程数+ 救济线程数 = 最大线程数
  • KeepAliveTime 救急线程最大存活时间(指的是救急线程 -当阻塞队列满的时候,创建救一定数量急线程)
  • unit 时间的单位(指的是救急线程)
  • workQueue 阻塞队列
  • 线程工厂
  • 阻塞队列已满且线程数达到最大值时所采取的拒绝策略

核心线程数多大合适?

CPU 密集型任务:

比如像加解密,压缩、计算等一系列需要大量耗费 CPU 资源的任务,大部分场景下都是纯 CPU 计算

核心线程数= CPU核心数 + 1

IO 密集型任务:

比如像 MySQL 数据库、文件的读写、网络通信等任务,这类任务不会特别消耗 CPU 资源,但是 IO 操作比较耗时,会占用比较多时间

线程数 = CPU 核心数 * (1 + IO 耗时/ CPU 耗时)

工具类提供的线程池

  • 复制代码
    1
    2
    3
    4
    newSingleThreadExecutor // 创建一个核心线程 newCachedThreadPool // 不创建核心线程,救急线程拉满 newSingleThreadExecutor // 创建固定数量的线程池

ps:阿里巴巴开发手册,不建议使用,让开发者创建自己了解的线程池

自定义线程工厂

可以自定义线程名称,线程池通常都需要自定义有意义的名称

拒绝策略

顶级接口

RejectedExecutionHandler (java.util.concurrent)

  • DiscardOldestPolicy // 丢掉阻塞队列最老的任务
  • AbortPolicy // 丢弃任务,并抛出异常,默认的拒绝策略
  • CallerRunsPolicy // 让调用者自己去执行任务,容易造成线程堵塞
  • DiscardPolicy // 静默的抛弃任务

阻塞队列

无界队列

队列大小无限制,常用的为无界的LinkedBlockingQueue,使用该队列做为阻塞队列时要尤其当心,当任务耗时较长时可能会导致大量新任务在队列中堆积最终导致OOM。Executors.newFixedThreadPool 采用就是 LinkedBlockingQueue,当QPS很高,发送数据很大,大量的任务被添加到这个无界LinkedBlockingQueue 中,导致cpu和内存飙升服务器挂掉。

有界队列

常用的有两类,一类是遵循FIFO原则的队列如ArrayBlockingQueue与有界的LinkedBlockingQueue,另一类是优先级队列如PriorityBlockingQueue。PriorityBlockingQueue中的优先级由任务的Comparator决定
使用有界队列时队列大小需和线程池大小互相配合,线程池较小有界队列较大时可减少内存消耗,降低cpu使用率和上下文切换,但是可能会限制系统吞吐量,可能造成部分任务丢失

同步移交队列

如果不希望任务在队列中等待而是希望将任务直接移交给工作线程,可使用SynchronousQueue作为等待队列。SynchronousQueue不是一个真正的队列,而是一种线程之间移交的机制(一手交钱、一手交货)。要将一个元素放入,必须有另一个线程正在等待接收这个元素。只有在使用无界线程池或者有饱和策略时才建议使用该队列。

最后

以上就是轻松自行车最近收集整理的关于Java线程池创建详解的全部内容,更多相关Java线程池创建详解内容请搜索靠谱客的其他文章。

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

评论列表共有 0 条评论

立即
投稿
返回
顶部