===== 使用场景 =====
* 看中延迟,任务队列使用SynchronousQueue队列
* 优点:每个任务提交后就能被执行,避免了在队列中等待的不可控时间
* 缺点:生产者,消费者线程频繁对齐使吞吐量下降
* 看中吞吐量,任务队列使用LinkedBlockingQueue
* 优点:队列做一个缓存,减少生产者、消费者之间线程对齐的次数(增加吞吐量)
* 缺点:在消费者遇到性能变差时。无法控制队列中的任务被执行的时间(可能很多任务会在队列中停留很久)
===== 测试 =====
* 10个生产者线程,提交1000w个任务
* 4个消费者线程
* SynchronousQueue性能:平均每秒提交处理100w个task
* LinkedBlockingQueue性能:平均每秒提交处理500w个task
===== 现有线程池的缺点 =====
* submit(),提交任务的时间和执行任务的时间没有分离
* 解决方案:自定义策略。任务提交时,设置超时时间(见下面代码)
* invokeAll() + AbortPolicy策略,如果有一个任务提交失败,则整体失败
* 解决方案:自定义策略。当任务提交失败时,将那个任务cancel掉,而不是抛出异常
* invokeAll() + DiscardPolicy策略,如果有一个任务提交失败,则invokeAll需要等到超时时间。因为被抛弃的任务根本没有被执行
* 解决方案:自定义策略。当任务提交失败时,将那个任务cancel掉
static class MyPolicy implements RejectedExecutionHandler {
private int submitTimeoutms;
static RejectedExecutionException exp = new RejectedExecutionException();
public MyPolicy(int submitTimeoutms) {
this.submitTimeoutms = submitTimeoutms;
}
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
try {
// queue 指线程池中的任务队列
boolean res = queue.offer(r, submitTimeoutms, TimeUnit.MILLISECONDS);
if(!res){
((FutureTask) r).cancel(true);
throw exp;
}
} catch (InterruptedException e1) {
throw exp;
}
}
}