线程执行器

    Java Executor framework是围绕Executor接口和它的子接口ExecutorService和ThreadPoolExecutor类实现了上述两接口。此机制将创建和执行任务分离,使用executor,仅需要实现Runnable对象,发送给executor。executor负责执行,初始化和运行必要的线程。
    executor framework的另外一个特点是Callalbe接口:它的主方法时call方法,且返回一个结果。当发送callalbe给executor时,会得到一个实现了Future接口的对象,它可以控制callalbe对象的状态和结果

创建线程执行器    

    ThreadPoolExecutor类有四个构造器,但是由于其复杂性,Java并发API提供了静态类Executors来构建executors和其他相关对象。可以直接使用ThreadPoolExecutor。
/*Executors的实例方法返回的是ExecutorService
 *缓存线程并重复利用,避免了线程创建,
 若缓存线程过多,导致系统负载加重
 */
ThreadPoolExecutor executor = (ThreadPoolExecutor)Executors.newCachedThreadPool();
getPoolSize()//线程池中实际线程数
getActiveCount()//线程池中正在执行task的线程数
getCompletedTaskCount()//线程池已经处理的task数
/*关闭线程池,必须显示执行 
 *不会执行被挂起的任务,当前正在执行的任务会继续执行
 最终返回被挂起的任务列表
 */
shutdownNow()
/*
 调用shutdown()或shutdownNow()方法,
 且执行器完成了shut down的过程,返回true
*/
isTerminated()
/**
 如果调用shutdown()或shutdownNow(),返回true 
*/
isShutdown()
/*
  此方法会阻塞调用线程,直到超时或执行器结束
*/
awaitTermination(long timeout,  TimeUnit  unit)

执行器中执行返回结果的任务  

    Callable:使用泛型的接口,必须指定返回的结果类型
    Future:此接口有一些方法获得Callable对象生成的结果并管理其状态    
public class FactorialCalculator implements Callable<Integer> {
   private Integer number;
   public FactorialCalculator(Integer number){
    this.number=number;
   }
   @Override
   public Integer call() throws Exception {
      int result = 1;  
      if ((num==0)||(num==1)) {
          result=1;
      } else {
          for (int i=2; i<=number; i++) {
             result*=i;
             TimeUnit.MILLISECONDS.sleep(20);
          }
      }
      return result;
   }     
}
public class Main {
  public static void main(String[] args) {
      ThreadPoolExecutor executor=(ThreadPoolExecutor)Executors.newFixedThreadPool(2);
      List<Future<Integer>> resultList=new ArrayList<>();
      Random random=new Random();
      for (int i=0; i<10; i++){
          Integer number= random.nextInt(10);
          FactorialCalculator calculator=new FactorialCalculator(number);
          Future<Integer> result=executor.submit(calculator);//返回为Future接口
          resultList.add(result);
      }
      do {
          for (int i=0; i<resultList.size(); i++) {
              Future<Integer> result=resultList.get(i);
        
          }
          try {
              TimeUnit.MILLISECONDS.sleep(50);
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
      } while (executor.getCompletedTaskCount()<resultList.size());
      for (int i=0; i<resultList.size(); i++) {
          Future<Integer> result=resultList.get(i);
          Integer number=null;
          try {
              number=result.get();
          } catch (InterruptedException e) {
            e.printStackTrace();
          } catch (ExecutionException e) {
            e.printStackTrace();
          }
      }
      executor.shutdown();
}

执行多个任务,处理第一个结果

List<TaskValidator> taskList=new ArrayList<>();
taskList.add(ldapTask);
taskList.add(dbTask);
ExecutorService executor=(ExecutorService)Executors.newCachedThreadPool();
try {
      result = executor.invokeAny(taskList);
      System.out.printf("Main: Result: %s\n",result);
} catch (InterruptedException e) {
      e.printStackTrace();
} catch (ExecutionException e) {
      e.printStackTrace();
}
invokeAny()//接受一组任务列表,并行发起,返回第一个结束且没有抛出异常的结果

运行多个task,处理所有结果

List<Future<Result>>resultList = executor.invokeAll(taskList);
executor.shutdown();
//执行所有的task,当所有的任务在超时之前都执行完成后返回他们的结果
invokeAll(Collection<? extends Callable<T>> tasks, long timeout,TimeUnit  unit)

executors中延迟运行task

ScheduledThreadPoolExecutor executor=(ScheduledThreadPoolExecutor)Executors.newScheduledThreadPool(1);
executor.schedule(task,i+1 , TimeUnit.SECONDS);
executor.shutdown();//
executor.awaitTermination(1, TimeUnit.DAYS);

/*
  默认情况下,所有那些等待delay挂起的任务将被执行,尽管
  执行器finalization,可以通过以下方法传入false
  被挂起的task不会被执行
*/
setExecuteExistingDelayedTasksAfterShutdownPolicy()

executors中周期运行task

/*
  第一参数:延迟时间
  第二参数:周期
  第三参数:时间单位
*/
ScheduledFuture<?> result=executor.scheduleAtFixedRate(task, 1, 2, TimeUnit.SECONDS);
scheduledFuture.getDelay()//到下次task执行时间
setContinueExistingPeriodicTasksAfterShutdownPolicy()//同上节方法,修改shutdown()默认行为

取消executors中的task

    使用Future的cancel()方法,如果task已经完成或已经被取消或其他原因不能被取消,返回false,task不会被取消。如果task在executor中等待获取线程,task被取消且不会开始执行。如果task已经运行,取决于cancel的参数,若位true,且task正在执行,将会被取消。若为false,task正在执行,不会被取消。

控制executor中正在finishing的task

    FutureTask类提供了done()方法,允许task执行完成后执行一些代码,用来做些post-process操作。此方法在task的结果被设置且状态变更为isDone状态后执行。
ExecutableTask executableTask=new ExecutableTask("Task ");//ExecutableTask实现Callalbe接口
resultTasks=new ResultTask(executableTask);//用FutureTask包装Callable对象
executor.submit(resultTasks);

在executor中分离正在发起的task,处理它们的结果

    CompletionService类有一个方法发送task给一个executor,和另外一个方法为在下一个task中获取Future对象。此行为的优点共享CompletionService对象,发送task给executor,其他task能处理结果。
public class ReportGenerator implements Callable<String> {
  private String sender;
  private String title;
  public ReportGenerator(String sender, String title){
    this.sender=sender;
    this.title=title;
  }
  @Override
  public String call() throws Exception {
    try {
      Long duration=(long)(Math.random()*10);
      System.out.printf("%s_%s: ReportGenerator: Generating a 
       report during %d seconds\n",this.sender,this.title,duration);
      TimeUnit.SECONDS.sleep(duration);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    String ret=sender+": "+title;
    return ret;
  }
}  
  public class ReportRequest implements Runnable {
      private String name;
      private CompletionService<String> service;
      public ReportRequest(String name, CompletionService<String> service){
        this.name=name;
        this.service=service;
      }
      @Override
      public void run() {    
          ReportGenerator reportGenerator=new ReportGenerator(name,"Report");
          service.submit(reportGenerator);//生成消息,并置入completeservice的队列中    
  }
  public class ReportProcessor implements Runnable {
      private CompletionService<String> service;
      private boolean end;
      public ReportProcessor (CompletionService<String> service){
         this.service=service;
         end=false;
      }
      public void run() {
         while (!end){
             try {
                Future<String> result=service.poll(20, TimeUnit.SECONDS);//从service队列中取得前task的结果
                if (result!=null) {
                   String report=result.get();
                   System.out.printf("ReportReceiver: Report Received: %s\n",report);
             }      
             } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
             }
         }
         System.out.printf("ReportSender: End\n");
      }
      public void setEnd(boolean end) {
         this.end = end;
      }
}      
  
  
ExecutorService executor=(ExecutorService)Executors.newCachedThreadPool();
CompletionService<String> service=new ExecutorCompletionService<>(executor);  
ReportRequest faceRequest=new ReportRequest("Face", service);
ReportRequest onlineRequest=new ReportRequest("Online", service);  
Thread faceThread=new Thread(faceRequest);
Thread onlineThread=new Thread(onlineRequest);
ReportProcessor processor=new ReportProcessor(service);
Thread senderThread=new Thread(processor);
faceThread.start();
onlineThread.start();
senderThread.start();

控制被executor拒绝的task

    当提供调用shutdown()后,再提交task给executor时候,此task会被rejected。RejectedExecutionHandler提供了一种机制处理被rejected的task。
public class RejectedTaskController implements 
RejectedExecutionHandler {
  @Override
  public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
    System.out.printf("RejectedTaskController: The task %s has 
been rejected\n",r.toString());
    System.out.printf("RejectedTaskController: %s\n",executor.
toString());
    System.out.printf("RejectedTaskController: Terminating: 
%s\n",executor.isTerminating());
    System.out.printf("RejectedTaksController: Terminated: 
%s\n",executor.isTerminated());
  }
}
executor.setRejectedExecutionHandler(controller);  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值