java多線程推薦使用方式及區別

/**
 * 參數介紹:
 * corePoolSize 核心線程數,指保留的線程池大小(不超過maximumPoolSize值時,線程池中最多有corePoolSize 個線程工作)。
 * maximumPoolSize 指的是線程池的最大大小(線程池中最大有corePoolSize 個線程可運行)
 * keepAliveTime 指的是空閒線程結束的超時時間(當一個線程不工作時,過keepAliveTime 長時間將停止該線程)。
 * unit 是一個枚舉,表示 keepAliveTime 的單位(有NANOSECONDS, MICROSECONDS,
 * MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS,7個可選值)。
 * workQueue 表示存放任務的隊列(存放需要被線程池執行的線程隊列)。
 * threadFactory - 執行程序創建新線程時使用的工廠。
 * handler - 由於超出線程範圍和隊列容量而使執行被阻塞時所使用的處理程序。
 */

@Configuration
public class CustomThreadFactory {


    private int corePoolSize = 3;
    private int maximumPoolSize = 10;
    private long keepAliveTime = 0;

    /**
     * 1、直接提交。工作隊列的默認選項是 SynchronousQueue,它將任務直接提交給線程而不保持它們。
     * 在此,如果不存在可用於立即運行任務的線程,則試圖把任務加入隊列將失敗,
     * 因此會構造一個新的線程。此策略可以避免在處理可能具有內部依賴性的請求集時出現鎖。
     * 直接提交通常要求無界 maximumPoolSizes, 以避免拒絕新提交的任務。
     * 當命令以超過隊列所能處理的平均數連續到達時,此策略允許無界線程具有增長的可能性。
     **/
    @Bean("getSynchronousQueueExecutorService")
    public ExecutorService getSynchronousQueueExecutorService() {
        ThreadFactory namedThreadFactory = new BasicThreadFactory.Builder().namingPattern("syn-pool-%d").daemon(true).build();
        return new ThreadPoolExecutor(corePoolSize, maximumPoolSize,
                keepAliveTime, TimeUnit.MILLISECONDS,
                new SynchronousQueue(), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
    }

    /**
     * 2、無界隊列。使用無界隊列(例如,不具有預定義容量的 LinkedBlockingQueue)將導致在所有 corePoolSize 線程都忙時新任務在隊列中等待。
     * 這樣,創建的線程就不會超過 corePoolSize。(因此,maximumPoolSize的值也就無效了。)當每個任務完全獨立於其他任務,即任務執行互不影響時,適合於使用無界隊列;
     * 例如,在 Web頁服務器中。這種排隊可用於處理瞬態突發請求,當命令以超過隊列所能處理的平均數連續到達時,此策略允許無界線程具有增長的可能性
     */
    @Bean("getLinkedBlockingQueueExecutorService")
    public ExecutorService getLinkedBlockingQueueExecutorService() {
        ThreadFactory namedThreadFactory = new BasicThreadFactory.Builder().namingPattern("link-pool-%d").daemon(true).build();
        return new ThreadPoolExecutor(corePoolSize, maximumPoolSize,
                keepAliveTime, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue(), namedThreadFactory);
    }

    /**
     * 3、有界隊列。當使用有限的 maximumPoolSizes時,有界隊列(如 ArrayBlockingQueue)有助於防止資源耗盡,但是可能較難調整和控制。
     * 隊列大小和最大池大小可能需要相互折衷:使用大型隊列和小型池可以最大限度地降低 CPU 使用率、操作系統資源和上下文切換開 銷,但是可能導致人工降低吞吐量。
     * 如果任務頻繁阻塞(例如,如果它們是 I/O邊界),則系統可能爲超過您許可的更多線程安排時間。使用小型隊列通常要求較大的池大小,CPU使用率較高,但是可能遇到不可接受的調度開銷,這樣也會降低吞吐量。
      *線程策略默認提供4種策略
     * RejectedExecutionHandler:無法處理線程的handler
     * RejectedExecutionHandler接口提供了對於拒絕任務的處理的自定方法的機會。在ThreadPoolExecutor中已經默認包含了4中策略源代碼如下
     * CallerRunsPolicy(直接運行run方法):線程調用運行該任務的 execute 本身。此策略提供簡單的反饋控制機制,能夠減緩新任務的提交速度。
     * 1.     public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {  
     * 2.                 if (!e.isShutdown()) {  
     * 3.                     r.run();  
     * 4.                 }  
     * 5.             } 
     * 這個策略顯然不想放棄執行任務。但是由於池中已經沒有任何資源了,那麼就直接使用調用線程本身run方法來執行。
     * AbortPolicy(拋異常):處理程序遭到拒絕將拋出運行時RejectedExecutionException
     * 1.     public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {  
     * 2.                 throw new RejectedExecutionException();  
     * 3.             } 
     *  這種策略直接拋出異常,丟棄任務。
     * DiscardPolicy(直接丟棄):不能執行的任務將被刪除
     * 1.     public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {  
     * 2.             } 
     *  這種策略和AbortPolicy幾乎一樣,也是丟棄任務,只不過他不拋出異常。
     * DiscardOldestPolicy(拋棄最老的線程):如果執行程序尚未關閉,則位於工作隊列頭部的任務將被刪除,然後
     * 重試執行程序(如果再次失敗,則重複此過程)
     * 1.     public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {  
     * 2.                 if (!e.isShutdown()) {  
     * 3.                     e.getQueue().poll();  
     * 4.                     e.execute(r);  
     * 5.                 }  
     *         } 
     * 該策略就稍微複雜一些,在pool沒有關閉的前提下首先丟掉緩存在隊列中的最早的任務,然後重新嘗試運行該任務。這個策略需要適當小心。
     */
    @Bean("getArrayBlockingQueueExecutorService")
    public ExecutorService getArrayBlockingQueueExecutorService() {
        ThreadFactory namedThreadFactory = new BasicThreadFactory.Builder().namingPattern("array-pool-%d").daemon(true).build();
        return new ThreadPoolExecutor(corePoolSize, maximumPoolSize,
                keepAliveTime, TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue(100), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
    }

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章