经常被重写的三个方法

ThreadPoolExecutor是可扩展的,通过查看源码可以发现,它提供了几个可以在子类化中改写的方法:beforeExecute,afterExecute,terminated.

protected void beforeExecute(Thread t, Runnable r) { }
protected void afterExecute(Runnable r, Throwable t) { }
protected void terminated() { }

在执行任务的线程中将调用beforeExecute和afterExecute等方法,在这些方法中还可以添加日志、计时、监视或者统计信息收集的功能。

无论任务是从run中正常返回,还是抛出一个异常而返回,afterExecute都会被调用。

如果任务在完成后带有一个Error,那么就不会调用afterExecute。

如果beforeExecute抛出一个RuntimeException,那么任务将不被执行,并且afterExecute也不会被调用。

在线程池完成关闭时调用terminated,也就是在所有任务都已经完成并且所有工作者线程也已经关闭后,terminated可以用来释放Executor在其生命周期里分配的各种资源,此外还可以执行发送通知、记录日志或者手机finalize统计等操作。

更改ThreadPoolExecutor的执行流程

正常情况下的,threadPoolExecutor的执行流程是:

1、线程数量低于core_size,不断的创建新的线程;
2、core_size已达到,将任务扔到队列里面;
3、core_size已达到,队列已经满了(插入任务失败),开始创建新线程;
4、线程数到max_size后,如果队列还是满的,抛出 RejectedExecutionException

这种执行过程,存在一个弊端:

1、当前线程数,超过core_size,会立刻将任务添加到队列中。如果队列设置的非常长,任务又很多的情况下,将会有频繁的任务入队和出队的操作。这种操作也是有一定资源及性能消耗的(理论上,作者未进行真机验证,网上有网友也指出过这个问题)。

2、线程数只有将 core_size和队列数量 占满的情况下,才启用新的线程(一直开到最大数量)。如果机器性能好,而core_size值设的小,会有资源浪费。

网上有人提出,设置新的执行流程:

1、未满core_size,不创建新的线程;
2、未满max,且core_size无空闲,创建新线程;
3、达到max,且全部无空闲,将任务丢进队列
4、达到max,且达到队列数,再抛出 RejectedExecutionException

这种也存在一种问题:

如果 core_size 远小于 max_size,则会大量创建新线程。(理论上,上线前的压测会有所改动)。

不过,如果项目存在瞬时大流出量,这种流程,则是一种不错的处理方案。

流程实现代码:https://github.com/li-shaoke/ExpandThreadPool

参考自:

http://blog.sina.com.cn/s/blog_6145ed8101015xfg.html

http://blog.csdn.net/linsongbin1/article/details/78275283

根据需要扩展java中的ThreadPoolExecutor的更多相关文章

  1. Java中使用ThreadPoolExecutor并行执行独立的单线程任务

    Java SE 5.0中引入了任务执行框架,这是简化多线程程序设计开发的一大进步.使用这个框架可以方便地管理任务:管理任务的生命周期以及执行策略. 在这篇文章中,我们通过一个简单的例子来展现这个框架所 ...

  2. java中ThrealLocal的理解

    目录 java中threadlocal的理解 一.threadlocal的生命周期和ThreadLocalMap的生命周期 二.ThreadLocal的作用 三.threadlocal示例 四.Inh ...

  3. java中的线程(3):线程池类 ThreadPoolExecutor「线程池的类型、参数、扩展等」

    官方文档: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html 1.简介 pu ...

  4. java中Executor、ExecutorService、ThreadPoolExecutor介绍(转)

    1.Excutor 源码非常简单,只有一个execute(Runnable command)回调接口 public interface Executor { /**     * Executes th ...

  5. java中Executor、ExecutorService、ThreadPoolExecutor介绍

    源码非常简单,只有一个execute(Runnable command)回调接口 public interface Executor { /**      * Executes the given c ...

  6. 浅谈Java中的补零扩展和补符号位扩展

    今天,魏屌出了一道题,题目如下: 定义一个大头序的byte[]a={-1,-2,-3,-4},转换成short[]b.问b[0]和b[1]分别是多少? 乍一看,这题不难,无非就是移位操作,再进行组合. ...

  7. Java中常用类(包装类扩展知识)

    Java常用类有哪些? 八大基本数据类型的包装类 包装类均位于java.lang包中,包装类和基本数据类型的对应关系如下表: 基本数据类型 包装类 byte Byte boolean Boolean ...

  8. java中 ExecutorService,Executor,ThreadPoolExecutor的用法

    package com; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Executor; import ...

  9. 第9章 Java中的线程池 第10章 Exector框架

    与新建线程池相比线程池的优点 线程池的分类 ThreadPoolExector参数.执行过程.存储方式 阻塞队列 拒绝策略 10.1 Exector框架简介 10.1.1 Executor框架的两级调 ...

随机推荐

  1. Linux pwn入门教程——格式化字符串漏洞

    本文作者:Tangerine@SAINTSEC 原文来自:https://bbs.ichunqiu.com/thread-42943-1-1.html 0×00 printf函数中的漏洞printf函 ...

  2. web API简介(三):客户端储存之Web Storage API

    概述 前篇:web API简介(二):客户端储存之document.cookie API 客户端储存从某一方面来说和动态网站差不多.动态网站是用服务端来储存数据,而客户端储存是用客户端来储存数据. W ...

  3. php函数式编程

    // 函数式编程 $users = array( array('id' => 1, 'name' => 'abc1', 'age' => 29, '性别' => '男'), a ...

  4. Thymeleaf教程入门到深入1:基础介绍

    1 介绍 1.1 简介 Thymeleaf是一个用于Web和独立Java环境的模板引擎,能够处理HTML.XML.JavaScript.CSS甚至纯文本.能轻易的与Spring MVC等Web框架进行 ...

  5. ajax 请求被终止 chrome查询发现请求状态status为canceled

    检查页面的network执行中发现页面被刷新了url改变了导致请求在请求过程中被终止了. 检查代码发现在 submit方法中最后写了个  location.reload();方法 来重载页面 虽然是卸 ...

  6. Eruda 一个被人遗忘的调试神器

    Eruda 一个被人遗忘的调试神器 引言   日常工作中再牛逼的大佬都不敢说自己的代码是完全没有问题的,既然有问题,那就也就有调试,说到调试工具,大家可能对于 fiddler.Charles.chro ...

  7. C# winform嵌入unity3D

    最近做项目需要winform嵌入unity的功能,由于完全没接触过这类嵌入的于是在网上搜,有一种方法是UnityWebPlayer插件,也开始琢磨了一段时间,不过一会发现在5.4版本以后这个东西就被淘 ...

  8. 201. Orchard学习 一、基础

    一.项目介绍 Orchard是一个免费和开源的社区交流项目,致力于在ASP.NET平台开发应用程序和可重用性组件.它将创建用于ASP.Net应用和扩展的共享组件,以及修改这些组件以便使其应用于终端用户 ...

  9. Android面试题(3)

    1.  请描述下Activity的生命周期. activity的生命周期方法有: onCreate().onStart().onReStart().onResume().onPause().onSto ...

  10. ruby执行字符串代码

    str = "a='abcd'; a.reverse" 字符串str为ruby代码,执行方法eval eval str => "dcba"