java 線程池(ExecutorService與Spring配置threadPoolTaskExecutor)


一、java ExecutorService實現

創建ExecutorService變量
private ExecutorService executor = null

      2.執行對應任務時,首先生成線程池

executor = Executors.newFixedThreadPool(線程池大小);

      3.循環執行線程

        for (String str : ids) {

 

                     executor.submit(new Callable<Void>() {

                                         @Override

                                         public Void call() throws Exception {

                                                 ......;//線程執行具體內容

                                                  return null;

                                         }

                     });

         }

          4.關閉線城池, shutdown關閉線城池,執行后程序會繼續往下進行,線城池會等待所有線程線程執行完畢后關閉。

executor.shutdown();

          5.設置阻塞等待awaitTermination, awaitTermination的作用是阻塞程序往下進行,使用之后程序會在所有線程執行完畢,關閉線城池之后才可以繼續進行。但是如果超過等待時間則會拋出InterruptedException異常

       try {

      //設置最大阻塞時間,所有線程任務執行完成再繼續往下執行

      executor.awaitTermination(1, TimeUnit.HOURS);

        long endTime = System.currentTimeMillis();         

      } catch (InterruptedException e) {

      }

@Service

public class DataImpl extends DataService {

         //設置線城池大小

         public static final int THREAD_POOL_FIX_SIZE = 100;

         @Autowired

         private DataDao dataDao;

         //線城池服務

         private ExecutorService executor = null;

 

         public void createData(Integer totalSize, Integer pageSize) {

                   //由於每次線程執行完畢會關閉線城池,所以要重新獲取線城池

                   executor = Executors.newFixedThreadPool(THREAD_POOL_FIX_SIZE);

                   //多線程調用

             for(List<String> id :ids){

                     executor.submit(new Callable<Void>() {

                                         @Override

                                         public Void call() throws Exception {

                                                  createData(id);

                                                  return null;

                                         }

                     });

             }

         //關閉線城池

           executor.shutdown();

      try {

      //設置最大阻塞時間,所有線程任務執行完成再繼續往下執行

      executor.awaitTermination(24, TimeUnit.HOURS);

      long endTime = System.currentTimeMillis();

  

      logger.info("=====================結束,用時"+ (endTime-startTime) + "毫秒" );

      

      } catch (InterruptedException e) {

      logger.info("======================超時" );

      }

         }

 

         private void createData(String id){

                   ……

         }

}

 

*注:1.Executors.newFixedThreadPool(THREAD_POOL_FIX_SIZE);要在每次調用方法的時候創建,線程全部執行完成之后shundown(),釋放所有線程,這樣可以保證執行任務時生成足夠線程,線程執行完立即釋放。

         2. ExecutorService可以寫在沒個類內,單獨問此類使用,不同類之間互不干擾;也可以也成公用方法,寫成公用方法后也會變成多類(多任務共享)同Spring線城池類似。

二、Spring 配置線程池(threadPoolTaskExecutor)

         

corePoolSize: 線程池維護線程的最少數量

keepAliveSeconds  線程池維護線程所允許的空閑時間

maxPoolSize   線程池維護線程的最大數量

queueCapacity 線程池所使用的緩沖隊列

rejectedExecutionHandler 線程池拒絕處理策略

當一個任務通過execute(Runnable)方法欲添加到線程池時:

l  如果此時線程池中的數量小於corePoolSize,即使線程池中的線程都處於空閑狀態,也要創建新的線程來處理被添加的任務。

l  如果此時線程池中的數量等於 corePoolSize,但是緩沖隊列 workQueue未滿,那么任務被放入緩沖隊列。

l  如果此時線程池中的數量大於corePoolSize,緩沖隊列workQueue滿,並且線程池中的數量小於maximumPoolSize,建新的線程來處理被添加的任務。

l  如果此時線程池中的數量大於corePoolSize,緩沖隊列workQueue滿,並且線程池中的數量等於maximumPoolSize,那么通過 handler所指定的策略來處理此任務。也就是:處理任務的優先級為:核心線程corePoolSize、任務隊列workQueue、最大線程 maximumPoolSize,如果三者都滿了,使用handler處理被拒絕的任務。

l  當線程池中的線程數量大於 corePoolSize時,如果某線程空閑時間超過keepAliveTime,線程將被終止。這樣,線程池可以動態的調整池中的線程數。

*注:1.spring 配置的線城池(threadPoolTaskExecutor)由於是spring創建注入的,在首次使用之后,會一直保持corePoolSize個空閑線程,它只會把多余的空閑線程在keepAliveSeconds 時間之后釋放,而且線城池不能調用shutdown()方法,否則再次調用,由於線程池已經關閉,會報錯。

   2. threadPoolTaskExecutor也可以在配置文件配置多個線城池,防止多有任務之間競爭,或者由於不同任務使用的線城池大小不同等情況。

 

 

三、ExecutorService與threadPoolTaskExecutor對比

 

---------------------
作者:黑桃K_程序猿
來源:CSDN
原文:https://blog.csdn.net/kai763253075/article/details/53033853 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM