聊聊Executor

Executor线程池的顶层设计

  • 1.任务:实现Runnabl接口或者Callable接口的类
  • 2.执行策略:Excutor
  • 3.计算结果: Future(异步计算的结果)

主要讲讲2

Executor将工作单元(Runnable)和执行策略分离开来。ThreadPoolExecutor是主要的实现类。ThreadPoolExecutor是这样设计的:

public ThreadPoolExecutor(int corePoolSize, // 基本线程数(线程池预热之后会常驻在内存中)
                              int maximumPoolSize,  // 线程池允许的最大线程数
                              long keepAliveTime, // 当超过基本线程池的线程空闲时间超过该值,线程退出线程池
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue, //任务队列
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) // 饱和策略
  • 1.如果当前运行的线程少于基本线程数,则创建新线程来执行任务(注意,执行这一步骤主要获取全局锁)
  • 2.如果运行的线程等于或者小于基本线程,则将任务加入任务阻塞队列
  • 3.如果无法将任务加入阻塞队列,队列已满,则创建新的线程来处理任务(注意,执行这一步骤主要获取全局锁)
  • 4.如果创建新的线程将使当前运行的线程超出最大线程数,任务将被拒绝,并调用饱和策略的方法
    因为步骤3需要获得全局锁,那将会是一个严重的可伸缩瓶颈,所以通过步骤2减少步骤3,而步骤2是不需要获取全局锁的。
    可以通过ThreadPoolExecutor创建三种类型的线程池(Executors的静态方法):

  • 1.FixedThreadPool

public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>(),
                                  threadFactory);
}

使用了无界队列LinkedBlockingQueue,所以根据上述,其实设置maximumPoolSize和keepAliveTime都是无效的。不会拒绝任务(调用饱和策略的方法)

  • 2.SingleThreadExecutor
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>(),
                                threadFactory));
}

同样使用了LinkedBlockingQueue,造成的效果和FixedThreadPool类似

  • 3.CachedThreadPool
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>(),
                                  threadFactory);
}

SynchronousQueue是没有容量的工作队列,但是CachedThreadPool中的最大线程数设置为无界。这意味着如果主线程提交任务的速度高于maximumPool中线程处理任务的速度,那么CachedThreadPool会不断创建新线程,极端情况下回耗尽CPU和内存资源。
可以通过ExecutorService的submit方法提交任务,返回Future等待回去任务执行结果。

参考资料:
java并发编程的艺术

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值