线程池面试问题汇总

为什么使用线程池,有哪些好处和缺点?

线程池属于常见的池化思想,因为创建线程和销毁线程,涉及到内存开辟和回收,属于重操作,因此是否可以通过集中多个线程放入池子中,需要的时候就从池子中获取,用完就归还。这就是线程池的池化思想。

当然线程池的线程使用,并不是从池子中获取线程,使用后归还。而是提交任务到池子中,由池子分配线程执行。

好处:把核心业务和非核心业务区分。减少线程的创建。
缺点:可能因为线程的相关配置,导致任务被抛弃(拒绝策略);任务执行异常或失败,无法告知调用方。

常见的线程池创建方法有哪些,又有哪些利弊,推荐那种方式?

创建线程池,有四种方式:

  1. Executors.newSingleThreadExecutor:创建单一线程池,即:corePoolSize=1,maximumPoolSize=1,线程池中只有一个线程。
  2. Executors.newCachedThreadPool:创建缓冲线程池,可以有无限多个线程。即:corePoolSize=0,maxThreadSize=Integer.MAX。
    缺点:每提交新的任务,就会创建一个线程,任务过多时,可能因为线程过多导致OOM。
    3 Executors.newFixedThreadPool:固定线程池。即corePoolSize=maxThreadSize,但是队列是LinkedBlockingQueue 无限大。
    缺点:当线程数量较小时,提交大量的任务,会存储在队列中,可能会因为队列任务过多,导致OOM。
    4 new ThreadPoolExecutor:手动创建线程池,根据需要配置相关属性。

推荐第四种创建方式,因为手动创建会设置核心线程、最大线程、缓冲队列等,不易出现OOM。

线程池的执行流程?

见:手写线程池

线程的拒绝策略有哪些,有什么缺陷?

拒绝策略有:

  1. AbortPolicy:直接拒绝,抛出RejectedExecutionException异常。缺点:会影响主线程执行。
  2. CallerRunsPolicy:调用者运行,即提交任务的业务线程执行,相当于没有利用线程池。缺点:主线程执行,没有利用到线程池,尤其在核心业务与非核心业务分离时,有可能因为要执行非核心业务,导致核心业务收到影响。
  3. DiscardOldestPolicy:抛弃最老的任务。默认从队列中,删除最老的任务,并提交当前的任务。缺点:存在任务丢失,同时该丢失还不会告知任务提交方。
  4. DiscardPolicy:丢弃策略,直接丢弃当前任务,什么也不做。缺点:什么都不做,如果是提交的FutureTask,会导致get时永远阻塞,因为丢弃任务后,无法变更FutrueTask的状态,当get时会永远阻塞。

默认的拒绝策略是:AbortPolicy。

推荐:建议对拒绝策略进行包装,首先如果业务方能接受抛出异常,就采用默认策略。否则还是尽量自定义拒绝策略,通过日志打印,输出固定格式的日志,根据日志监控,告知相关业务方。
请注意:如果拒绝策略是日志数据,那么存在一个问题,即Runnable接口,并没有输出被执行任务的具体内容,因此需要进行包装,见:线程池扩展 中的“业务异常捕获”,或者“再拯救一次”。

线程池的核心线程数如何确定?

计算密集型

计算密集型的阻塞点不在cpu利用上,因此一般可以设置线程数=cpu核数,或者核数+1。

IO密集型

涉及到数据库读写、网络请求都可以认为是IO密集型,此时线程数=NcpuUcpu(1+W/C)。其中:Ncpu=cpu核数。Ucpu=cpu利用率,介于0-1,一般都是希望100%利用。W/C=等待时间/计算时间。可以通过stopwatch计算线程执行完成的W/C

说明:上述线程池数量的计算,还是要结合实际,因为你也不清楚系统已经创建了多少个线程池。最终还是要根据执行情况,优化调整。

线程池能否实现页面可视化操作?

可以,线程池提供了corePoolSize,maxThreadSize的set接口,因此可以根据需要动态调整线程池。具体见:线程池扩展 中的“线程池可视化操作”。

调度线程池是如何运作的?

调度线程池主要是为了解决定时任务的相关缺陷。

Timer定时任务

利用Timer类实现

线程池注意事项

  1. ThreadLocal:线程池不支持ThreadLocal的传递,因此使用时要注意,如果需要传递ThreadLocal,请使用TransmittableThreadLocal。
  2. 线程名称:建议根据业务名称作为线程名称,方便排查问题,根据线程名称就可以定位问题。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值