java_多线程调用笔记2
/**
* JDK5.0或以上 java.util.concurrent.ThreadPoolExecutor 线程参数配置说明
*
* 线程池可以减少每个任务调用的开销,也就是减少单个任务的等待时间.
* 当使用单线程时,任务需要进行排队,在线程池中,每个任务都有自己的线程,不再排队,实现多任务同时处理.
*
* 1、java.util.concurrent.ThreadPoolExecutor的常用构造方法如下:
*
* ThreadPoolExecutor(
* int corePoolSize, // 线程池维护线程的最少线程数(核心线程数)
* int maximumPoolSize, // 线程池维护线程的最大线程数
* long keepAliveTime, // 线程池维护线程所允许的空闲时间
* TimeUnit unit, // 线程池维护线程所允许的空闲时间的单位
* BlockingQueue<Runnable> workQueue, // 线程池所使用的缓冲队列
* RejectedExecutionHandler handler) // handler: 线程池对拒绝任务的处理策略
*
* 2、线程池任务管理
* 当一个任务将被添加到线程池中时:
* a、如果当前线程数小于corePoolSize,即使有空闲线程,也会创建新的线程来处理新增任务;
* b、如果当前线程数等于corePoolSize,如果缓冲队列未满,该任务被放入缓冲队列;
* c、如果当前线程数等于corePoolSize,且冲队列已满,如果当前线程数小于maximumPoolSize, 就创建新的线程来处理新增任务;
* d、如果当前线程数等于maximumPoolSize,且冲队列已满,将会使用handler所指定的策略来处理任务.
*
* 3、线程池满载时的处理策略
* 当线程池中的线程数等于maximumPoolSize时,提供4个现有的策略
* a、ThreadPoolExecutor.AbortPolicy:表示拒绝任务并抛出异常
* b、ThreadPoolExecutor.DiscardPolicy:表示拒绝任务但不做任何动作
* c、ThreadPoolExecutor.CallerRunsPolicy:表示拒绝任务,并在调用者的线程中直接执行该任务【常用项】
* d、ThreadPoolExecutor.DiscardOldestPolicy:表示先丢弃任务队列中的第一个任务,然后把这个任务加进队列
*
* 4、线程池的缓存队列策略
* BlockingQueue只是一个接口,常用的实现类有LinkedBlockingQueue 和 ArrayBlockingQueue。
* a、用LinkedBlockingQueue的好处在于没有大小限制.这样的话,因为队列不会满,所以 execute() 不会抛出异常
* 而线程池中运行的线程数也永远不会超过 corePoolSize 个,keepAliveTime 参数也就没有意义了.
* b、用ArrayBlockingQueue, 该队列的长度有限制.【常用项】
*
* 5、线程池线程管理策略
* 当一个线程空闲,超过一定的时间(keepAliveTime)时,线程池会判断,
* 如果当前运行的线程数大于corePoolSize,那么这个线程就被停掉。所以线程池的所有任务完成后,它最终会收缩到 corePoolSize 的大小。
*/
/**
* 线程管理工具
* <!-- spring配置管理,线程池初始化和销毁 -->
* <bean id="threadTools" class="util.thread.ThreadTools" init-method ="init" destroy-method ="stop">
* </bean>
*/
public class ThreadTools {
public static int cpuSize = Runtime.getRuntime().availableProcessors();
public static int perCpuThreads = cpuSize > 8 ? 20 : 30;//每个cpu的默认运行线程数
//最小保留线程数,池中所保存的线程数,默认核心线程数为 cpu个数* perCpuThreads
public static int corePoolSize = cpuSize * perCpuThreads;
public static int maximumPoolSize = corePoolSize;//最大线程数=默认线程
public static int keepAliveTime = 1; //当总线程数大于默认线程数时,多余的空闲线程等待新任务的最长时间
public static int maxQueueSize = corePoolSize * 5; //最大等待线程队列数,默认线程*5
public static int maxThreadGroup = cpuSize; //最大任务数
public static int setBatchCount = cpuSize < 15 ? 15 : cpuSize ; //最大每批次数
public static List <ThreadGroupService<String>> threadGroupServiceList = null;// 当前任务列表
public static LinkedBlockingQueue<Runnable> waitthreadQueue = null; //池中线程等待队列
public static ThreadLocal<InfoQueue> infoThreadLocal = new ThreadLocal< InfoQueue >(); //线程执行信息
//构造一个线程池
public static ThreadPoolExecutor threadPool = null;
private ThreadTools(){
//ThreadTools.init();
};//禁止实例化
/**
* 功能说明:判断线程池是否繁忙
* @param addSize 新增线程数量
* @return boolean
*/
public static boolean isBusy(int addSize){
int queueCnt = threadPool.getQueue().size(); // 获取线程队列中排队线程数
if ( queueCnt>0 //队列中已有排队线程
&& queueCnt + addSize > maxQueueSize * 0.90 ) { //新增线程 > 最大队列线程90%
return true;
}else{
return MonitorService.isMemory(); //||MonitorService.isThread();
}
}
public static boolean isBusy(){
return isBusy(1);
}
/**
* 功能说明:初始化任务
* @param threadGroupName 任务名(采用中文,一般命名方式"功能模块名_用户名")
* @size 预计当前组下的线程个数
* @isMaxThreadGroup 是否判断排队任务个数大于拟定值,一般新启任务要判断,但在中途执行过程中创建子任务不用判断。
* @throws Exception
*
*/
public static synchronized boolean initThreadGroup(final String threadGroupName,int size,boolean isMaxThreadGroup) throws Exception{
if( ThreadGroupService.getThreadGroup(threadGroupName, threadGroupServiceList)!= null ){
throw new Exception("本次任务正在执行中,请稍后再试!");
}
int countGroup = threadGroupServiceList.size();
if(isMaxThreadGroup && countGroup > maxThreadGroup){
throw new Exception("系统中已存在太多任务正在执行,请稍后再试!");
}
boolean isBusy = (isMaxThreadGroup && isBusy(size));//中途执行过程中不进行忙的判断
ThreadGroupService<String> groupService = new ThreadGroupService<String>(threadGroupName,isBusy,countGroup+1);
threadGroupServiceList.add(groupService);
return isBusy;
}
public static synchronized boolean initThreadGroup(final String threadGroupName) throws Exception{
return initThreadGroup(threadGroupName,0,false);
}
public static synchronized boolean initThreadGroup(final String threadGroupName,int size) throws Exception{
return initThreadGroup(threadGroupName,size,false);
}
/**
* 功能说明:加入单个线程到线程池中执行
* @param task 线程
* @param threadGroupName 任务名
* @return 返回结果列表
*/
public static void addThread(final Callable<String> task, final String threadGroupName) throws Exception{
ThreadGroupService<String> threadGroupService = ThreadGroupService.getThreadGroup(threadGroupName, threadGroupServiceList);
if(threadGroupService!=null){//组正在执行中
threadGroupService.submit(task,threadPool);
}else{
//没有初始化组
initThreadGroup(threadGroupName);
addThread(task, threadGroupName);
}
}
/**
* 功能说明:加入单个线程到线程池中执行
* @param task 线程
* @param threadGroupName 任务名
* @param nextSecond 延迟启动(毫秒)
* @return 返回结果列表
*/
public static void addThread(
final Callable<String> task, final String threadGroupName, final int nextSecond) throws Exception{
//当前线程延迟启动
Callable<String> tempTread = new Callable<String>() {
public String call() throws Exception {
Thread.sleep( nextSecond );
addThread(task,threadGroupName);
return null;
}
};
threadPool.submit(tempTread);
}
/**
* 功能说明:侦听任务运行直到全部结束
* @param threadGroupName 任务名
* @param infoQueue 返回结束任务运行信息
* @param waitTime 等待时间(毫秒)
* @return 返回结束线程标志 0 正常 1 后台队列执行 -1 出错
* @throws Execution
*/
public static int listenThreadEnd(
final String threadGroupName, InfoQueue infoQueue, final int waitTime)throws Exception{
int flag = 0 ;
ThreadGroupService<String> threadGroupService = null;
try {
if (waitTime > 0) {
Thread.sleep(waitTime + 200);// 延迟等待时间
}else{
Thread.sleep(1000);
}
threadGroupService = ThreadGroupService.getThreadGroup(threadGroupName, threadGroupServiceList);
if (threadGroupService != null) {
if(threadGroupService.isRuning()){//任务处于运行状态,等待各线程执行结束
for (int j = 0; j < threadGroupService.getSize(); j++) {
Future<String> future = threadGroupService.getFutureQueue().poll();
if(future!=null){
String temp = future.get();
if(null != temp && "-1".equals(temp)){
infoQueue.offer(temp + "\r\n");//返回线程计算结果
flag = -1;
}
}
}
}else{
//任务处于非运行状态,直接返回
flag = 1;
infoQueue.offer("任务【"+threadGroupName+"】转入任务管理队列后台运行计算,请稍后在任务管理页面查看处理结果!您现在可以处理其他事情! \r\n");
}
infoThreadLocal.set(infoQueue);
}
} catch (Exception e) {
flag = -1;
throw new Exception("在线程工具类运行过程中出错了!"+ e.toString());
} finally{
if(flag!=1) {
if(threadGroupService!=null){
//中断执行此任务的线程
for(Future<String> futur : threadGroupService.getFutureQueue()){
futur.cancel(true);
}
}
threadGroupServiceList.remove(threadGroupService);
}else{
//设置任务组结束
if(threadGroupService!=null) threadGroupService.setEnd();
}
}
return flag;
}
public static int listenThreadEnd(final String threadGroupName,InfoQueue infoQueue)throws Exception{
return listenThreadEnd(threadGroupName,infoQueue,0);
}
public static int listenThreadEnd(final String threadGroupName,final int waitTime)throws Exception{
return listenThreadEnd(threadGroupName,new InfoQueue(),waitTime);
}
public static int listenThreadEnd(final String threadGroupName)throws Exception{
return listenThreadEnd(threadGroupName,new InfoQueue(),0);
}
/**
* 强制取消任务
* @param threadGroupName
*/
public static void cancelGroup(final String threadGroupName) throws Exception{
ThreadGroupService<String> threadGroupService = null;
try{
threadGroupService= ThreadGroupService.getThreadGroup(threadGroupName, threadGroupServiceList);
if(threadGroupService!=null){
//中断执行此任务的线程
for(Future<String> futur : threadGroupService.getFutureQueue()){
futur.cancel(true);
}
}
}catch (Exception e) {
throw new Exception("在线程工具类中取消任务出错了!"+ e.toString());
}finally{
if(threadGroupService!=null)threadGroupServiceList.remove(threadGroupService);
}
}
/**
* 返回当前用户任务线程执行信息
* @return
*/
public static InfoQueue getInfoQueue() {
InfoQueue temp = infoThreadLocal.get();
infoThreadLocal.remove();
return temp;
}
/**
* 功能说明:关闭线程池
*/
public static synchronized void stop(){
if(threadPool!=null) {
threadPool.shutdown();
threadPool = null;
}
if(threadGroupServiceList!=null){
threadGroupServiceList.clear();
threadGroupServiceList = null;
}
if(waitthreadQueue!=null){
waitthreadQueue.clear();
waitthreadQueue = null;
}
if(infoThreadLocal!=null){
infoThreadLocal.remove();
infoThreadLocal = null;
}
}
/**
* 功能说明:初始化线程池
*/
public static synchronized void init() {
if(threadPool!=null){
stop();
}
threadToolParameter();//线程参数获取方法
threadGroupServiceList = new java.util.ArrayList<ThreadGroupService<String>>();
waitthreadQueue = new LinkedBlockingQueue<Runnable>();
threadPool = new ThreadPoolExecutor(
corePoolSize,
maximumPoolSize,
keepAliveTime,
TimeUnit.SECONDS,
waitthreadQueue,
new ThreadPoolExecutor.CallerRunsPolicy());
}
/**
* 获取线程池中参数,如果数据库中没有对应的记录,则使用默认的参数值
* @throws IllegalAccessException
* @throws InstantiationException
* @throws BeansException
*/
private static void threadToolParameter() {
Properties pros= SystemData.getProps();
if(pros!=null){
String hhh_perCpuThreads =pros.getProperty("hhh_perCpuThreads");//每个cpu的默认运行线程数
if(hhh_perCpuThreads!=null && !"--".equals(hhh_perCpuThreads)){
perCpuThreads=Integer.valueOf(hhh_perCpuThreads);
}
String hhh_corePoolSize =pros.getProperty("hhh_corePoolSize");//池中所保存的线程数
if(hhh_corePoolSize!=null && !"--".equals(hhh_corePoolSize)){
corePoolSize=Integer.valueOf(hhh_corePoolSize);
}
String hhh_maximumPoolSize =pros.getProperty("hhh_maximumPoolSize");//最大线程数
if(hhh_maximumPoolSize!=null && !"--".equals(hhh_maximumPoolSize)){
maximumPoolSize=Integer.valueOf(hhh_maximumPoolSize);
}
String hhh_keepAliveTime =pros.getProperty("hhh_keepAliveTime");//空闲线程等待新任务的最长时间
if(hhh_keepAliveTime!=null && !"--".equals(hhh_keepAliveTime)){
keepAliveTime=Integer.valueOf(hhh_keepAliveTime);
}
String hhh_maxQueueSize =pros.getProperty("hhh_maxQueueSize");//最大等待线程队列数
if(hhh_maxQueueSize!=null && !"--".equals(hhh_maxQueueSize)){
maxQueueSize=Integer.valueOf(hhh_maxQueueSize) ;
}
String hhh_maxThreadGroup =pros.getProperty("hhh_maxThreadGroup");//最大任务数
if(hhh_maxThreadGroup!=null && !"--".equals(hhh_maxThreadGroup)){
maxThreadGroup= Integer.valueOf(hhh_maxThreadGroup);
}
String hhh_setBatchCount =pros.getProperty("hhh_setBatchCount");//最大每批次套账数
if(hhh_setBatchCount!=null && !"--".equals(hhh_setBatchCount)){
setBatchCount=Integer.valueOf(hhh_setBatchCount);
}
}
}
/**
* 设置cpu线程数据,同时更新相关参数
* @param cpuThreads cpu线程数据
*/
public static void setPerCpuThreads(int cpuThreads){
perCpuThreads = cpuThreads;
corePoolSize = cpuSize * perCpuThreads;
threadPool.setCorePoolSize(corePoolSize);
setBatchCount = cpuSize < 15 ? 15 : cpuSize ; //最大每批次数
maxQueueSize = corePoolSize * 5;
}
/**
* 按最大每批次数生成
*/
public static List<List<Integer>> batchSet (int[] fsets){
int len = fsets.length;
int count = 0;
List<Integer> batchList = new ArrayList<Integer>();
List<List<Integer>> list = new ArrayList<List<Integer>>();
for(int i = 0 ;i < len ;i++){
if( count >= setBatchCount){
list.add(batchList);
count = 0;
batchList = new java.util.ArrayList<Integer>();
}
batchList.add(fsets[i]);
count++;
}
list.add(batchList);//最后一批
return list;
}
}

浙公网安备 33010602011771号