面经系列:java并发编程(4)

  • 为什么用线程池?

线程池就是管理一系列线程的资源池,当有任务要处理时,直接从线程池中获取空闲线程来处理,处理后线程不会被销毁,而是等待下一个任务。

线程池的好处:

  1. 减少资源消耗
  2. 提高响应速度
  3. 提高线程的可管理性
  • 如何创建线程池?

  • 1.  通过ThreadPoolExecutor构造函数创建,可以提供自定义配置,如核心线程数、最大线程数、存活时间、工作队列等。(推荐)

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(

    corePoolSize,

    maximumPoolSize,

    keepAliveTime,//非核心工作线程在阻塞队列位置等待的时间

    unit,//时间单位

    workQueue //任务在没有核心工作线程处理时,先放在工作队列中

);

ThreadPoolExecutor 3 个最重要的参数:

corePoolSize : 任务队列未达到队列容量时,最大可以同时运行的线程数量

maximumPoolSize : 任务队列中存放的任务达到队列容量的时候,当前可以同时运行的线程数量变为最大线程数。

workQueue: 新任务来的时候会先判断当前运行的线程数量是否达到核心线程数,如果达到的话,新任务就会被存放在队列中。

  • 2. 通过Executors工厂类

FixedThreadPool:该方法返回一个固定线程数量的线程池。该线程池中的线程数量始终不变。当有一个新的任务提交时,线程池中若有空闲线程,则立即执行。若没有,则新的任务会被暂存在一个任务队列中,待有线程空闲时,便处理在任务队列中的任务。

SingleThreadExecutor: 该方法返回一个只有一个线程的线程池。若多余一个任务被提交到该线程池,任务会被保存在一个任务队列中,待线程空闲,按先入先出的顺序执行队列中的任务。

CachedThreadPool: 该方法返回一个可根据实际情况调整线程数量的线程池。线程池的线程数量不确定,但若有空闲线程可以复用,则会优先使用可复用的线程。若所有线程均在工作,又有新的任务提交,则会创建新的线程处理任务。所有线程在当前任务执行完毕后,将返回线程池进行复用。

ScheduledThreadPool:定时任务线程池。

  • 线程池的饱和策略

饱和:同时运行线程数量 达到 最大线程数量 + 工作队列已满

  1. ThreadPoolExecutor.AbortPolicy: 抛出 RejectedExecutionException来拒绝新任务的处理。(默认策略)
  2. ThreadPoolExecutor.CallerRunsPolicy: 调用执行自己的线程运行任务,也就是直接在调用execute方法的线程中运行(run)被拒绝的任务,如果执行程序已关闭,则会丢弃该任务。影响程序的整体性能,但保证每个任务请求被执行。
  3. ThreadPoolExecutor.DiscardPolicy: 不处理新任务,直接丢弃掉。
  4. ThreadPoolExecutor.DiscardOldestPolicy: 此策略将丢弃最早的未处理的任务请求。
  • 线程池处理任务的流程

图片来源网络,如有侵权请联系删除。

  • 如何设计一个能够根据任务的优先级来执行的线程池?

使用PriorityBlockingQueue (优先级阻塞队列)作为任务队列。

要想让 PriorityBlockingQueue 实现对任务的排序,传入其中的任务必须是具备排序能力的,方式有两种:提交到线程池的任务实现 Comparable 接口,并重写 compareTo 方法来指定任务之间的优先级比较规则。创建 PriorityBlockingQueue 时传入一个 Comparator 对象来指定任务之间的排序规则(推荐)。

存在的问题及解决方案:

1.PriorityBlockingQueue是无界的,可能堆积大量请求,导致OOM

继承PriorityBlockingQueue并重写offer方法,插入元素超过指定值返回false

2.饥饿问题

引入等待时间,等待时间过长的任务提升其优先级

由于需要对队列中的元素进行排序操作以及保证线程安全(并发控制采用的是可重入锁 ReentrantLock),因此会降低性能。 无法避免

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值