线程池Demo之  

   
   
   
   
  1. ThreadPoolTaskExecutor 
    (1)编写测试类

Java代码
 
   
   
   
   
  1. import org.springframework.core.task.TaskExecutor; 
  2.  
  3. public class TaskExecutorExample { 
  4. private TaskExecutor taskExecutor; 
  5. public TaskExecutorExample(TaskExecutor taskExecutor) {     
  6. this.taskExecutor = taskExecutor;   
  7. public void printMessages() {     
  8. for(int i = 0; i < 25; i++) {       
  9. taskExecutor.execute(new MessagePrinterTask("Message" + i));     
  10. }   
  11. private class MessagePrinterTask implements Runnable {     
  12. private String message;     
  13. public MessagePrinterTask(String message) {       
  14. this.message = message;     
  15. }     
  16. public void run() {       
  17. System.out.println(message);     
  18. }  
(2)spring的配置
Xml代码 
 
   
   
   
   
  1. <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">      
  2.     <property name="corePoolSize" value="5" />      
  3.     <property name="maxPoolSize" value="10" />      
  4.     <property name="queueCapacity" value="25" />   
  5. bean>   
  6. <bean id="taskExecutorExample" class="powercn.TaskExecutorExample">     
  7.     <constructor-arg ref="taskExecutor" />   
  8. bean>   
线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为:

 
   
   
   
   
  1. ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, 
  2. long keepAliveTime, TimeUnit unit, 
  3. BlockingQueue workQueue, 
  4. RejectedExecutionHandler handler) 
 
   
   
   
   
  1. corePoolSize: 线程池维护线程的最少数量 
  2. maximumPoolSize:线程池维护线程的最大数量 
  3. keepAliveTime: 线程池维护线程所允许的空闲时间 
  4. unit: 线程池维护线程所允许的空闲时间的单位 
  5. workQueue: 线程池所使用的缓冲队列 
  6. handler: 线程池对拒绝任务的处理策略 
一个任务通过 execute(Runnable)方法被添加到线程池,任务就是一个 Runnable类型的对象,任务的执行方法就是 Runnable类型对象的run()方法。

当一个任务通过execute(Runnable)方法欲添加到线程池时:

如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。

如果此时线程池中的数量等于 corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。

如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理被添加的任务。

如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。

也就是:处理任务的优先级为:
核心线程corePoolSize、任务队列workQueue、最大线程maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。

当线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。

unit可选的参数为java.util.concurrent.TimeUnit中的几个静态属性:
NANOSECONDS、MICROSECONDS、MILLISECONDS、SECONDS。

workQueue我常用的是:java.util.concurrent.ArrayBlockingQueue

handler有四个选择:
ThreadPoolExecutor.AbortPolicy()
抛出java.util.concurrent.RejectedExecutionException异常
ThreadPoolExecutor.CallerRunsPolicy()
重试添加当前的任务,他会自动重复调用execute()方法
ThreadPoolExecutor.DiscardOldestPolicy()
抛弃旧的任务
ThreadPoolExecutor.DiscardPolicy()
抛弃当前的任务
 
   
   
   
   
  1. <bean id="taskExecutor" 
  2.   class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor" 
  3.   scope="singleton" lazy-init="true"> 
  4.   <property name="corePoolSize" value="${threadpool.corePoolSize}" /> 
  5.   <property name="queueCapacity" value="${threadpool.queueCapacity}" /> 
  6.   <property name="maxPoolSize" value="${threadpool.maxPoolSize}" /> 
  7.   <property name="keepAliveSeconds" value="${threadpool.keepAliveSeconds}" /> 
  8.   <property name="rejectedExecutionHandler"> 
  9.    <bean class="${threadpool.rejectedExecutionHandler}" /> 
  10.   property> 
  11.  
  12.  
  13.   <property name="threadNamePrefix" value="${threadpool.threadNamePrefix}" /> 
  14.  bean> 
properties文件:
 
   
   
   
   
  1. threadpool.corePoolSize=5 
  2. threadpool.queueCapacity=30 
  3. threadpool.maxPoolSize=20 
  4. threadpool.keepAliveSeconds=5 
  5. threadpool.rejectedExecutionHandler=java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy 
  6. threadpool.threadNamePrefix=myThread 

 (3)调用
Java代码 
 
   
   
   
   
  1. ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml");     
  2. TaskExecutorExample te = (TaskExecutorExample)appContext.getBean("taskExecutorExample");    
  3. te.printMessages();    
  4. System.out.println("11111111111111111111111");