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;
 }
}

 

 

 

posted @ 2014-04-23 14:03  波风甲穵  阅读(235)  评论(0)    收藏  举报