1. 程式人生 > >Spring 執行緒池應用

Spring 執行緒池應用

源自:http://zjriso.iteye.com/blog/771706 
1.瞭解 TaskExecutor介面 

    Spring的TaskExecutor介面等同於java.util.concurrent.Executor介面。 實際上,它存在的主要原因是為了在使用執行緒池的時候,將對Java 5的依賴抽象出來。 這個介面只有一個方法execute(Runnable task),它根據執行緒池的語義和配置,來接受一個執行任務。最初建立TaskExecutor是為了在需要時給其他Spring元件提供一個執行緒池的抽象。 例如ApplicationEventMulticaster元件、JMS的 AbstractMessageListenerContainer和對Quartz的整合都使用了TaskExecutor抽象來提供執行緒池。 當然,如果你的bean需要執行緒池行為,你也可以使用這個抽象層。 




2. TaskExecutor介面的實現類 

    (1)SimpleAsyncTaskExecutor 類 

這個實現不重用任何執行緒,或者說它每次呼叫都啟動一個新執行緒。但是,它還是支援對併發總數設限,當超過執行緒併發總數限制時,阻塞新的呼叫,直到有位置被釋放。如果你需要真正的池,請繼續往下看。 



    (2)SyncTaskExecutor類 

這個實現不會非同步執行。相反,每次呼叫都在發起呼叫的執行緒中執行。它的主要用處是在不需要多執行緒的時候,比如簡單的test case。 



    (3)ConcurrentTaskExecutor 類 

這個實現是對Java 5 java.util.concurrent.Executor類的包裝。有另一個備選, ThreadPoolTaskExecutor類,它暴露了Executor的配置引數作為bean屬性。很少需要使用ConcurrentTaskExecutor, 但是如果ThreadPoolTaskExecutor不敷所需,ConcurrentTaskExecutor是另外一個備選。 


    (4)SimpleThreadPoolTaskExecutor 類 

這個實現實際上是Quartz的SimpleThreadPool類的子類,它會監聽Spring的生命週期回撥。當你有執行緒池,需要在Quartz和非Quartz元件中共用時,這是它的典型用處。 

    (5)ThreadPoolTaskExecutor 類 

它不支援任何對java.util.concurrent包的替換或者下行移植。Doug Lea和Dawid Kurzyniec對java.util.concurrent的實現都採用了不同的包結構,導致它們無法正確執行。 這個實現只能在Java 5環境中使用,但是卻是這個環境中最常用的。它暴露的bean properties可以用來配置一個java.util.concurrent.ThreadPoolExecutor,把它包裝到一個TaskExecutor中。如果你需要更加先進的類,比如ScheduledThreadPoolExecutor,我們建議你使用ConcurrentTaskExecutor來替代。 


    (6)TimerTaskExecutor類 

這個實現使用一個TimerTask作為其背後的實現。它和SyncTaskExecutor的不同在於,方法呼叫是在一個獨立的執行緒中進行的,雖然在那個執行緒中是同步的。 

    (7)WorkManagerTaskExecutor類 

這個實現使用了CommonJ WorkManager作為其底層實現,是在Spring context中配置CommonJ WorkManager應用的最重要的類。和SimpleThreadPoolTaskExecutor類似,這個類實現了WorkManager介面,因此可以直接作為WorkManager使用。 

3.執行緒池Demo之  ThreadPoolTaskExecutor 

    (1)編寫測試類 
Java程式碼  收藏程式碼
  1. import org.springframework.core.task.TaskExecutor;  
  2. public class TaskExecutorExample {  
  3.     private TaskExecutor taskExecutor;  
  4.     public TaskExecutorExample(TaskExecutor taskExecutor) {      
  5.         this.taskExecutor = taskExecutor;    
  6.     }  
  7.     public void printMessages() {      
  8.         for(int i = 0; i < 25; i++) {        
  9.             taskExecutor.execute(new MessagePrinterTask("Message" + i));      
  10.         }    
  11.     }  
  12.     private class MessagePrinterTask implements Runnable {      
  13.         private String message;      
  14.         public MessagePrinterTask(String message) {        
  15.             this.message = message;      
  16.         }      
  17.         public void run() {        
  18.             System.out.println(message);      
  19.         }  
  20.     }  
  21. }  


  (2)spring的配置 
Xml程式碼  收藏程式碼
  1. <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">                 
  2.                   <!-- 執行緒池活躍的執行緒數 -->     
  3.     <property name="corePoolSize" value="5" />   
  4.                    <!-- 執行緒池最大活躍的執行緒數 -->    
  5.     <property name="maxPoolSize" value="10" />   
  6.                    <!-- 佇列的最大容量 -->    
  7.     <property name="queueCapacity" value="25" />  
  8. </bean>  
  9. <bean id="taskExecutorExample" class="powercn.TaskExecutorExample">   
  10.     <constructor-arg ref="taskExecutor" />  
  11. </bean>  


(3)呼叫 
Java程式碼  收藏程式碼
  1. ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml");  
  2. TaskExecutorExample te = (TaskExecutorExample)appContext.getBean("taskExecutorExample");  
  3. te.printMessages();  
  4. System.out.println("11111111111111111111111");