ThreadPoolExecutor自定义线程池示例

常用例子

		import com.google.common.util.concurrent.ThreadFactoryBuilder;

        ThreadFactory factory = new ThreadFactoryBuilder().setNameFormat("渭水-task-%d").build();

		// 方法1 factory由google的common实现 主要是可以自定义线程的名字
        int  maximumPoolSize =Runtime.getRuntime().availableProcessors() * 4 +1;
        int corePoolSize = maximumPoolSize/2;
        ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize,maximumPoolSize,5,TimeUnit.SECONDS
            , new LinkedBlockingQueue<>(1024),factory, new ThreadPoolExecutor.AbortPolicy());
         executor.allowCoreThreadTimeOut(true);

		// 方法2 直接使用本地的 Executors.defaultThreadFactory()
        ThreadPoolExecutor executor2 = new ThreadPoolExecutor(corePoolSize,maximumPoolSize,3,TimeUnit.SECONDS
            , new LinkedBlockingQueue<>(1024), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
        executor2.allowCoreThreadTimeOut(true);

上面使用的是ThreadPoolExecutor.AbortPolicy()
也就是说,当线程数已经等于maximumPoolSize,队列里也放满了,如果还submit任务,submit就会抛出异常。

参数解析

1线程池刚创建时,里面没有一个线程。任务队列是作为参数传进来的。不过,就算队列里面有任务,线程池也不会马上执行它们。
2当调用 execute() 方法添加一个任务时,线程池会做如下判断:

  • 如果正在运行的线程数量小于 corePoolSize,那么马上创建线程运行这个任务;
  • 如果正在运行的线程数量大于或等于 corePoolSize,那么将这个任务放入队列。
  • 如果这时候队列满了,而且正在运行的线程数量小于 maximumPoolSize,那么还是要创建线程运行这个任务;
  • 如果队列满了,而且正在运行的线程数量大于或等于 maximumPoolSize,那么线程池会抛出异常,告诉调用者“我不能再接受任务了”。
  • 当一个线程完成任务时,它会从队列中取下一个任务来执行。
  • 当一个线程无事可做,超过一定的时间(keepAliveTime)时,线程池会判断,如果当前运行的线程数大于 corePoolSize,那么这个线程就被停掉。所以线程池的所有任务完成后,它最终会收缩到 corePoolSize 的大小。

如果线程池已经满了可是还有新的任务提交怎么办?

线程池已满的定义,是指运行线程数==maximumPoolSize,并且workQueue是有界队列并且已满(如果是无界队列当然永远不会满);
在默认的 ThreadPoolExecutor.AbortPolicy 中,处理程序遭到拒绝将抛出运行时RejectedExecutionException。
在 ThreadPoolExecutor.CallerRunsPolicy 中,线程调用运行该任务的execute 本身。此策略提供简单的反馈控制机制,能够减缓新任务的提交速度。
在 ThreadPoolExecutor.DiscardPolicy 中,不能执行的任务将被删除。
在 ThreadPoolExecutor.DiscardOldestPolicy 中,如果执行程序尚未关闭,则位于工作队列头部的任务将被删除,然后重试执行程序(如果再次失败,则重复此过程)
当然也可以自己实现处理策略类,继承RejectedExecutionHandler接口即可,该接口只有一个方法:
void rejectedExecution(Runnable r, ThreadPoolExecutor executor);
void rejectedExecution(Runnable r, ThreadPoolExecutor executor);

参考文档

【阿里开发规范】ThreadPoolExecutor自定义线程池示例(亲测)

https://blog.csdn.net/Jack_SivenChen/article/details/53394058

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值