Java面试(2)之 多线程

线程池的结构及原理

一, 线程池的参数:

corePoolSize: 线程池核心线程大小; 默认情况下这些线程不会被销毁,除非设置了allowCoreThreadTimeOut

maximumPoolSize: 线程池最大线程数量

keepAliveTime: 空闲线程存活时间

TimeUnit: 空闲线程存活时间及单位

workQueue: 工作队列

1, ArrayBlockingQueue: 基于数组的有界阻塞队列,按FIFO排序。

2, LinkedBlockingQuene: 基于链表的无界阻塞队列(其实最大容量为Interger.MAX),按照FIFO排序。由于该队列的近似无界性,因此使用该工作队列时,参数maxPoolSize其实是不起作用的。

3, SynchronousQuene: 一个不缓存任务的阻塞队列,生产者放入一个任务必须等到消费者取出这个任务。也就是说新任务进来时,不会缓存,而是直接被调度执行该任务,如果没有可用线程,则创建新线程,如果线程数量达到maxPoolSize,则执行拒绝策略。

4, PriorityBlockingQueue: 具有优先级的无界阻塞队列,优先级通过参数Comparator实现。

handler: 拒绝策略(RejectedExecutionHandler)

  1. AbortPolicy: 直接抛异常
  2. CallerRunsPolicy:让调用者帮着跑这个任务
  3. DiscardOldestPolicy:丢弃队列里最老的那个任务,执行当前任务
  4. DiscardPolicy:不处理,直接扔掉

二, 线程池的处理过程:

  1. 先判断线程池中的核心线程们是否空闲,如果空闲,就把这个新的任务指派给某一个空闲线程去执行。如果没有空闲,并且当前线程池中的核心线程数还小于 corePoolSize,那就再创建一个核心线程。
  2. 如果线程池的线程数已经达到核心线程数,并且这些线程都繁忙,就把这个新来的任务放到等待队列中去。
  3. 如果等待队列又满了,那么查看一下当前线程数是否到达maximumPoolSize,如果还未到达,就继续创建线程。如果已经到达了,就交给RejectedExecutionHandler来决定怎么处理这个任务。

----------------------------------------------------------------------------------------------------------------

线程数设置和CPU数的关系

一般说来,大家认为线程池的大小经验值应该这样设置:(其中N为CPU的个数)

  • 如果是CPU密集型应用,则线程池大小设置为N+1
  • 如果是IO密集型应用,则线程池大小设置为2N+1(因为io读数据或者缓存的时候,线程等待,此时如果多开线程,能有效提高cpu利用率)

但是,IO优化中,这样的估算公式可能更适合: 最佳线程数目 = ((线程等待时间+线程CPU时间)/线程CPU时间 )* CPU数目 线程等待时间所占比例越高,需要越多线程。线程CPU时间所占比例越高,需要越少线程。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱编程的Loren

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值