成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

java線程池的原理學(xué)習(xí)(二)

oujie / 928人閱讀

摘要:接上文線程池的原理學(xué)習(xí)簡單介紹,線程池類,繼承自構(gòu)造方法提供了四種構(gòu)造方法實(shí)現(xiàn)這里只介紹一種有必要對每個(gè)參數(shù)解釋一下池中所保存的線程數(shù),包括空閑線程。文檔中提供了一個(gè)可以暫停和恢復(fù)的線程池例子運(yùn)行原理線程池的原理學(xué)習(xí)三

接上文:java線程池的原理學(xué)習(xí)

ThreadPoolExecutor簡單介紹

ThreadPoolExecutor,線程池類,繼承自 AbstractExecutorService

public class ThreadPoolExecutor extends AbstractExecutorService 
構(gòu)造方法

ThreadPoolExecutor 提供了四種構(gòu)造方法實(shí)現(xiàn)(這里只介紹一種):

 public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

有必要對每個(gè)參數(shù)解釋一下:

corePoolSize - 池中所保存的線程數(shù),包括空閑線程。

maximumPoolSize - 池中允許的最大線程數(shù)。

keepAliveTime - 當(dāng)線程數(shù)大于核心時(shí),此為終止前多余的空閑線程等待新任務(wù)的最長時(shí)間。

unit - keepAliveTime 參數(shù)的時(shí)間單位。

workQueue - 執(zhí)行前用于保持任務(wù)的隊(duì)列。此隊(duì)列僅保持由 execute 方法提交的 Runnable 任務(wù)。

threadFactory - 執(zhí)行程序創(chuàng)建新線程時(shí)使用的工廠。

handler - 由于超出線程范圍和隊(duì)列容量而使執(zhí)行被阻塞時(shí)所使用的處理程序。

配置規(guī)則

為了便于跨大量上下文使用,此類提供了很多可調(diào)整的參數(shù)和擴(kuò)展鉤子 (hook)。jdk文檔中建議在通常情況下,使用 Executors 提供的工廠方法配置,也就是提供好了的線程池。若非要手動(dòng)配置,需要遵循以下規(guī)則:

核心和最大池大小

ThreadPoolExecutor 將根據(jù) corePoolSizemaximumPoolSize 設(shè)置的邊界自動(dòng)調(diào)整池大小。當(dāng)新任務(wù)在方法 execute(java.lang.Runnable) 中提交時(shí):
1.運(yùn)行的線程少于 corePoolSize,則創(chuàng)建新線程來處理請求,即使其他輔助線程是空閑的。
2:運(yùn)行的線程多于 corePoolSize 而少于 maximumPoolSize,則把任務(wù)放進(jìn)隊(duì)列,由空閑線程從隊(duì)列中取任務(wù),僅當(dāng)隊(duì)列滿時(shí)才創(chuàng)建新線程。
3:如果設(shè)置的 corePoolSizemaximumPoolSize 相同,則創(chuàng)建了固定大小的線程池。
4:如果將 maximumPoolSize 設(shè)置為基本的無界值(如 Integer.MAX_VALUE ),則允許池適應(yīng)任意數(shù)量的并發(fā)任務(wù)。

還要注意以下兩點(diǎn):

在大多數(shù)情況下,核心和最大池大小僅基于構(gòu)造器來設(shè)置,不過也可以使用 setCorePoolSize(int)setMaximumPoolSize(int) 進(jìn)行動(dòng)態(tài)更改。

當(dāng)池中的線程數(shù)大于 corePoolSize 的時(shí)候,多余的線程會(huì)等待 keepAliveTime 長的時(shí)間,如果無請求可處理就自行銷毀。

創(chuàng)建新線程

使用 ThreadFactory 創(chuàng)建新線程。如果沒有另外說明,則在同一個(gè) ThreadGroup 中一律使用 Executors.defaultThreadFactory() 創(chuàng)建線程,并且這些線程具有相同的 NORM_PRIORITY 優(yōu)先級和非守護(hù)進(jìn)程狀態(tài)。通過提供不同的 ThreadFactory,可以改變線程的名稱、線程組、優(yōu)先級、守護(hù)進(jìn)程狀態(tài),等等。如果從 newThread 返回 null 時(shí) ThreadFactory 未能創(chuàng)建線程,則執(zhí)行程序?qū)⒗^續(xù)運(yùn)行,但不能執(zhí)行任何任務(wù)。

ThreadFactory 是線程工廠,它是一個(gè)接口:

public interface ThreadFactory {
    Thread newThread(Runnable r);
}

ThreadPoolExecutor 中的 threadFactory 是由 Executors 工具類提供的:

public static ThreadFactory defaultThreadFactory() {
        return new DefaultThreadFactory();
}
static class DefaultThreadFactory implements ThreadFactory {
        private static final AtomicInteger poolNumber = new AtomicInteger(1);
        private final ThreadGroup group;
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        private final String namePrefix;

        DefaultThreadFactory() {
            SecurityManager s = System.getSecurityManager();
            group = (s != null) ? s.getThreadGroup() :
                                  Thread.currentThread().getThreadGroup();
            namePrefix = "pool-" +
                          poolNumber.getAndIncrement() +
                         "-thread-";
        }

        public Thread newThread(Runnable r) {
           ////創(chuàng)建的線程以“pool-N-thread-M”命名,N是該工廠的序號,M是線程號
            Thread t = new Thread(group, r,
                                  namePrefix + threadNumber.getAndIncrement(),
                                  0); 
            //設(shè)為非后臺(tái)線程                      
            if (t.isDaemon())
                t.setDaemon(false);
            //優(yōu)先級為normal    
            if (t.getPriority() != Thread.NORM_PRIORITY)
                t.setPriority(Thread.NORM_PRIORITY);
            return t;
        }
    }

DefaultThreadFactory 是一個(gè)靜態(tài)內(nèi)部類

排隊(duì)策略

前面說到,當(dāng)線程池中運(yùn)行的線程等于或多于 corePoolSize,則 Executor 始終首選將請求加入隊(duì)列,而不添加新的線程,將任務(wù)加入隊(duì)列有三種策略(具體參見jdk文檔)。

被拒絕的任務(wù)

兩種情況下,新提交的任務(wù)將會(huì)被拒絕:

當(dāng) Executor 已經(jīng)關(guān)閉

Executor 將有限邊界用于最大線程和工作隊(duì)列容量,且已經(jīng)飽和

被拒絕的任務(wù), execute 方法都將調(diào)用其 RejectedExecutionHandlerRejectedExecutionHandler.rejectedExecution(java.lang.Runnable, java.util.concurrent.ThreadPoolExecutor) 方法。下面提供了四種預(yù)定義的處理程序策略:

在默認(rèn)的 ThreadPoolExecutor.AbortPolicy 中,處理程序遭到拒絕將拋出運(yùn)行時(shí) RejectedExecutionException。
ThreadPoolExecutor.CallerRunsPolicy 中,線程調(diào)用運(yùn)行該任務(wù)的 execute 本身。此策略提供簡單的反饋控制機(jī)制,能夠減緩新任務(wù)的提交速度。
ThreadPoolExecutor.DiscardPolicy 中,不能執(zhí)行的任務(wù)將被刪除。
ThreadPoolExecutor.DiscardOldestPolicy 中,如果執(zhí)行程序尚未關(guān)閉,則位于工作隊(duì)列頭部的任務(wù)將被刪除,然后重試執(zhí)行程序(如果再次失敗,則重復(fù)此過程)。

定義和使用其他種類的 RejectedExecutionHandler 類也是可能的,但這樣做需要非常小心,尤其是當(dāng)策略僅用于特定容量或排隊(duì)策略時(shí)。

鉤子方法

此類提供兩個(gè) protected 可重寫的 鉤子方法:

protected void beforeExecute(Thread t, Runnable r) { }
protected void afterExecute(Runnable r, Throwable t) { }

這兩種方法分別在執(zhí)行 每個(gè)任務(wù) 之前和之后調(diào)用。它們可用于操縱執(zhí)行環(huán)境;注意這里是每個(gè)任務(wù),即每次運(yùn)行新任務(wù)時(shí)都會(huì)執(zhí)行一遍。例如,重新初始化 ThreadLocal 、搜集統(tǒng)計(jì)信息或添加日志條目。此外,還可以重寫方法 terminated() 來執(zhí)行 Executor 完全終止后需要完成的所有特殊處理。
如果鉤子 (hook) 或回調(diào)方法拋出異常,則內(nèi)部輔助線程將依次失敗并突然終止。

jdk文檔中提供了一個(gè)可以暫停和恢復(fù)的線程池例子:

class PausableThreadPoolExecutor extends ThreadPoolExecutor {
   private boolean isPaused;
   private ReentrantLock pauseLock = new ReentrantLock();
   private Condition unpaused = pauseLock.newCondition();

   public PausableThreadPoolExecutor(...) { super(...); }
   protected void beforeExecute(Thread t, Runnable r) {
     super.beforeExecute(t, r);
     pauseLock.lock();
     try {
       while (isPaused) unpaused.await();
     } catch(InterruptedException ie) {
       t.interrupt();
     } finally {
       pauseLock.unlock();
     }
   }
   public void pause() {
     pauseLock.lock();
     try {
       isPaused = true;
     } finally {
       pauseLock.unlock();
     }
   }
   public void resume() {
     pauseLock.lock();
     try {
       isPaused = false;
       unpaused.signalAll();
     } finally {
       pauseLock.unlock();
     }
   }
 }
ThreadPoolExecutor運(yùn)行原理

java線程池的原理學(xué)習(xí)(三)

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/64433.html

相關(guān)文章

  • java線程池的原理學(xué)習(xí)(三)

    摘要:接上文線程池的原理學(xué)習(xí)二深入剖析線程池的五種狀態(tài)類中將線程狀態(tài)分為了以下五種可以接受新任務(wù)并且處理進(jìn)入隊(duì)列中的任務(wù)不接受新任務(wù),但是仍然執(zhí)行隊(duì)列中的任務(wù)不接受新任務(wù)也不執(zhí)行隊(duì)列中的任務(wù)所有任務(wù)中止,隊(duì)列為空,進(jìn)入該狀態(tài)下的任務(wù)會(huì)執(zhí)行方法方法 接上文:java線程池的原理學(xué)習(xí)(二) ThreadPoolExecutor深入剖析 線程池的五種狀態(tài) ThreadPoolExecutor 類中...

    mgckid 評論0 收藏0
  • 后端ing

    摘要:當(dāng)活動(dòng)線程核心線程非核心線程達(dá)到這個(gè)數(shù)值后,后續(xù)任務(wù)將會(huì)根據(jù)來進(jìn)行拒絕策略處理。線程池工作原則當(dāng)線程池中線程數(shù)量小于則創(chuàng)建線程,并處理請求。當(dāng)線程池中的數(shù)量等于最大線程數(shù)時(shí)默默丟棄不能執(zhí)行的新加任務(wù),不報(bào)任何異常。 spring-cache使用記錄 spring-cache的使用記錄,坑點(diǎn)記錄以及采用的解決方案 深入分析 java 線程池的實(shí)現(xiàn)原理 在這篇文章中,作者有條不紊的將 ja...

    roadtogeek 評論0 收藏0
  • Java線程池的工作原理,好處和注意事項(xiàng)

    摘要:線程池的工作原理一個(gè)線程池管理了一組工作線程,同時(shí)它還包括了一個(gè)用于放置等待執(zhí)行任務(wù)的任務(wù)隊(duì)列阻塞隊(duì)列。使用線程池可以對線程進(jìn)行統(tǒng)一的分配和監(jiān)控。線程池的注意事項(xiàng)雖然線程池是構(gòu)建多線程應(yīng)用程序的強(qiáng)大機(jī)制,但使用它并不是沒有風(fēng)險(xiǎn)的。 線程池的工作原理一個(gè)線程池管理了一組工作線程, 同時(shí)它還包括了一個(gè)用于放置等待執(zhí)行 任務(wù)的任務(wù)隊(duì)列(阻塞隊(duì)列) 。 一個(gè)線程池管理了一組工作線程, 同時(shí)它還...

    ZweiZhao 評論0 收藏0
  • java線程池的原理學(xué)習(xí)

    摘要:而中直接將任務(wù)交給運(yùn)行再來看創(chuàng)建一個(gè)保存所有的結(jié)果運(yùn)行任務(wù)依次取結(jié)果這里使用是為了等待運(yùn)行完成,如果沒完成就會(huì)阻塞如果發(fā)生異常,則取消所有任務(wù)續(xù)線程池的原理學(xué)習(xí)二 Executor接口 如果查看jdk文檔,會(huì)發(fā)現(xiàn)java線程池都源自于這個(gè)超級接口Executor,但是這個(gè)接口本身比較簡單: public interface Executor { /** 在未來...

    Taonce 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<