根据需要扩展java中的ThreadPoolExecutor
经常被重写的三个方法
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的更多相关文章
- Java中使用ThreadPoolExecutor并行执行独立的单线程任务
		
Java SE 5.0中引入了任务执行框架,这是简化多线程程序设计开发的一大进步.使用这个框架可以方便地管理任务:管理任务的生命周期以及执行策略. 在这篇文章中,我们通过一个简单的例子来展现这个框架所 ...
 - java中ThrealLocal的理解
		
目录 java中threadlocal的理解 一.threadlocal的生命周期和ThreadLocalMap的生命周期 二.ThreadLocal的作用 三.threadlocal示例 四.Inh ...
 - java中的线程(3):线程池类 ThreadPoolExecutor「线程池的类型、参数、扩展等」
		
官方文档: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html 1.简介 pu ...
 - java中Executor、ExecutorService、ThreadPoolExecutor介绍(转)
		
1.Excutor 源码非常简单,只有一个execute(Runnable command)回调接口 public interface Executor { /** * Executes th ...
 - java中Executor、ExecutorService、ThreadPoolExecutor介绍
		
源码非常简单,只有一个execute(Runnable command)回调接口 public interface Executor { /** * Executes the given c ...
 - 浅谈Java中的补零扩展和补符号位扩展
		
今天,魏屌出了一道题,题目如下: 定义一个大头序的byte[]a={-1,-2,-3,-4},转换成short[]b.问b[0]和b[1]分别是多少? 乍一看,这题不难,无非就是移位操作,再进行组合. ...
 - Java中常用类(包装类扩展知识)
		
Java常用类有哪些? 八大基本数据类型的包装类 包装类均位于java.lang包中,包装类和基本数据类型的对应关系如下表: 基本数据类型 包装类 byte Byte boolean Boolean ...
 - java中 ExecutorService,Executor,ThreadPoolExecutor的用法
		
package com; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Executor; import ...
 - 第9章 Java中的线程池 第10章 Exector框架
		
与新建线程池相比线程池的优点 线程池的分类 ThreadPoolExector参数.执行过程.存储方式 阻塞队列 拒绝策略 10.1 Exector框架简介 10.1.1 Executor框架的两级调 ...
 
随机推荐
- Android热修复——Tinker的集成
			
前言 做前端开发的都知道,当我们项目做完了以后,都会把应用上传到应用市场上供用户下载使用,比如上传到应用宝啊,应用汇啊,360啊,小米,华为,魅族啊,等等但是,有时候我们会经常遇到一些很扯淡的事情,刚 ...
 - Java 虚拟机的内存结构
			
Java虚拟机运行时数据区 整个程序执行过程中,JVM会用一段空间来存储程序执行期间需要用到的数据和相关信息,这段空间一般被称作为Runtime Data Area(运行时数据区),也就是我们常说的J ...
 - python中除法的几种类型
			
传统除法:直接后缀小数点,同样结果是和最大的小数点对齐 >>> 1/2 0 >>> 1.0/2 0.5 >>> 1/2.0 0.5 >> ...
 - oracle中常见的对表、表空间和视图的操作
			
创建表:create table t1(key1 type default 0,key2 type not null) 删除表:drop table t1; 删除表数据:truncate table ...
 - 本地电脑无法连接到MySQL
			
问题描述: ERROR 1130 (HY000): Host 'localhost' is not allowed to connect to this MySQL server 首先网上的问题大部分 ...
 - GraphX之Pregel(BSP模型-消息传递机制)学习
			
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreem ...
 - SQLi Lab的视频教程和文字教程
			
SQLi Lab 系列的文字和视频(需要FQ),讲解的很好 SQLi Lab Series - Introduction SQLi Lab Series - Error Based SQLi Lab ...
 - window傻瓜式安装tensorflow
			
最近学习一下,比较热门的深度学习. 本人英文差,记性差,什么都差,哈哈. 折腾过ub安装,虽然成功,但是总是觉得不好用. 发现tenorflow已经可以很傻瓜的在windows下安装了....... ...
 - 常用的npm指令总结
			
一.安装指令,通常是全局安装 npm install <package name> -g 二.移除全局安装包 npm uninstall <package name> -g 三 ...
 - Hadoop项目实战-用户行为分析之应用概述(二)
			
1.概述 本课程的视频教程地址:<项目整体概述> 本节给大家分享的主题如下图所示: 下面我开始为大家分享第二节的内容——<项目整体概述>,下面开始今天的分享内容. 2.内容 从 ...