亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何理解Java常見知識點中的線程池

發布時間:2021-11-20 15:46:13 來源:億速云 閱讀:110 作者:柒染 欄目:軟件技術

這期內容當中小編將會給大家帶來有關如何理解Java常見知識點中的線程池,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

線程池的基本思想是一種對象池,在程序啟動時就開辟一塊內存空間,里面存放了眾多(未死亡)的線程,池中線程執行調度由池管理器來處理。當有線程任務時,從池中取一個,執行完成后線程對象歸池,這樣可以避免反復創建線程對象所帶來的性能開銷,節省了系統的資源。

一. 使用線程池的好處

降低資源消耗:通過重復利用已創建的線程降低線程創建和銷毀造成的消耗(每個線程需要大約1MB內存,線程開的越多,消耗的內存也就越大,最后死機)。;

提高響應速度:當任務到達時,任務可以不需要等到線程創建就能立即執行;

提高線程的可管理性:線程是稀缺資源,如果無限制的創建,不僅會消耗系統資源,還會降低系統的穩定性,使用線程池可以進行統一的分配,調優和監控。

對線程進行一些簡單的管理,比如:延時執行、定時循環執行的策略等,運用線程池都能進行很好的實現

一個線程池包括以下四個基本組成部分

  • 線程池管理器(ThreadPool):用于創建并管理線程池,包括 創建線程池,銷毀線程池,添加新任務;

  • 工作線程(WorkThread):線程池中線程,在沒有任務時處于等待狀態,可以循環的執行任務;

  • 任務接口(Task):每個任務必須實現的接口,以供工作線程調度任務的執行,它主要規定了任務的入口,任務執行完后的收尾工作,任務的執行狀態等;

  • 任務隊列(taskQueue):用于存放沒有處理的任務。提供一種緩沖機制。

二. ThreadPoolExecutor類

講到線程池,要重點介紹java.uitl.concurrent.ThreadPoolExecutor類,ThreadPoolExecutor是線程池中最核心的一個類。

我們可以通過ThreadPoolExecutor來創建一個線程池

new ThreadPoolExecutor(corePoolSize, maximumPoolSize,keepAliveTime, 
milliseconds,runnableTaskQueue, threadFactory,handler);
  • corePoolSize(線程池的基本大小):當提交一個任務到線程池時,線程池會創建一個線程來執行任務,即使其他空閑的基本線程能夠執行新任務也會創建線程,等到需要執行的任務數大于線程池基本大小時就不再創建。如果調用了線程池的prestartAllCoreThreads方法,線程池會提前創建并啟動所有基本線程。

  • maximumPoolSize(線程池最大大小):線程池允許創建的最大線程數。如果隊列滿了,并且已創建的線程數小于最大線程數,則線程池會再創建新的線程執行任務。值得注意的是如果使用了無界的任務隊列這個參數就沒什么效果。

  • runnableTaskQueue(任務隊列):用于保存等待執行的任務的阻塞隊列。

  • ThreadFactory:用于設置創建線程的工廠,可以通過線程工廠給每個創建出來的線程設置更有意義的名字,Debug和定位問題時非常又幫助。

  • RejectedExecutionHandler(拒絕策略):當隊列和線程池都滿了,說明線程池處于飽和狀態,那么必須采取一種策略處理提交的新任務。這個策略默認情況下是AbortPolicy,表示無法處理新任務時拋出異常。以下是JDK1.5提供的四種策略。n AbortPolicy:直接拋出異常。

  • keepAliveTime(線程活動保持時間):線程池的工作線程空閑后,保持存活的時間。所以如果任務很多,并且每個任務執行的時間比較短,可以調大這個時間,提高線程的利用率。

  • TimeUnit(線程活動保持時間的單位):可選的單位有天(DAYS),小時(HOURS),分鐘(MINUTES),毫秒(MILLISECONDS),微秒(MICROSECONDS, 千分之一毫秒)和毫微秒(NANOSECONDS, 千分之一微秒)。

向線程池提交任務

我們可以通過execute()或submit()兩個方法向線程池提交任務,不過它們有所不同

  • execute()方法沒有返回值,所以無法判斷任務知否被線程池執行成功

    threadsPool.execute(new Runnable() {
      
    @Override
      public void run() {
      // TODO Auto-generated method stub
     }
    });
  • submit()方法返回一個future,那么我們可以通過這個future來判斷任務是否執行成功,通過future的get方法來獲取返回值

    try {
       Object s = future.get();
     } catch (InterruptedException e) {
     // 處理中斷異常
     } catch (ExecutionException e) {
     // 處理無法執行任務異常
     } finally {
     // 關閉線程池
     executor.shutdown();
    }

    線程池的關閉

我們可以通過shutdown()或shutdownNow()方法來關閉線程池,不過它們也有所不同

  • shutdown的原理是只是將線程池的狀態設置成SHUTDOWN狀態,然后中斷所有沒有正在執行任務的線程。

  • shutdownNow的原理是遍歷線程池中的工作線程,然后逐個調用線程的interrupt方法來中斷線程,所以無法響應中斷的任務可能永遠無法終止。shutdownNow會首先將線程池的狀態設置成STOP,然后嘗試停止所有的正在執行或暫停任務的線程,并返回等待執行任務的列表。

ThreadPoolExecutor執行的策略

線程數量未達到corePoolSize,則新建一個線程(核心線程)執行任務

線程數量達到了corePools,則將任務移入隊列等待

隊列已滿,新建線程(非核心線程)執行任務

隊列已滿,總線程數又達到了maximumPoolSize,就會由(RejectedExecutionHandler)拋出異常

四種拒絕策略

  • ThreadPoolExecutor.AbortPolicy() 拋出java.util.concurrent.RejectedExecutionException異常

  • ThreadPoolExecutor.DiscardPolicy() 拋棄當前的任務

  • ThreadPoolExecutor.DiscardOldestPolicy() 拋棄舊的任務 (隊列中的第一個任務替換為當前新進來的任務執行)

  • ThreadPoolExecutor.CallerRunsPolicy() 重試添加當前的任務,他會自動重復調用execute()方法

三. Java通過Executors提供四種線程池

1. CachedThreadPool():可緩存線程池

  • 線程數無限制

  • 有空閑線程則復用空閑線程,若無空閑線程則新建線程 一定程序減少頻繁創建/銷毀線程,減少系統開銷

CachedThreadPool創建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閑線程,若無可回收,則新建線程

2. FixedThreadPool():定長線程池

  • 可控制線程最大并發數(同時執行的線程數)

  • 超出的線程會在隊列中等待

  • 如果某個線程因為執行異常而結束,那么線程池會補充一個新線程。

3. ScheduledThreadPool()

  • 定時線程池。

  • 支持定時及周期性任務執行。

newscheduledThreadPool創建一個定長線程池,支持定時及周期性任務執行。延遲執行示例代碼如下.表示延遲1秒后每3秒執行一次

public class ThreadPoolExecutorTest3 {
    public static void main(String[] args) {
        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
        scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
            public void run() {
                System.out.println(Thread.currentThread().getName() + ": delay 1 seconds, and excute every 3 seconds");
            }
        }, 1, 3, TimeUnit.SECONDS);// 表示延遲1秒后每3秒執行一次
    }
}

4. SingleThreadExecutor():單線程化的線程池

  • 有且僅有一個工作線程執行任務

  • 所有任務按照指定順序執行,即遵循隊列的入隊出隊規則

newSingleThreadExecutor創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行,如果這個唯一的線程因為異常結束,那么會有一個新的線程來替代它。此線程池保證所有任務的執行順序按照任務的提交順序執行

四. 線程池的監控

通過繼承線程池并重寫線程池的beforeExecute,afterExecute和terminated方法,我們可以在任務執行前,執行后和線程池關閉前干一些事情。如監控任務的平均執行時間,最大執行時間和最小執行時間等。這幾個方法在線程池里是空方法。

上述就是小編為大家分享的如何理解Java常見知識點中的線程池了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

益阳市| 襄汾县| 齐河县| 玉屏| 宁德市| 兴文县| 浦江县| 信阳市| 乐昌市| 轮台县| 蓝田县| 武鸣县| 茌平县| 遂平县| 无极县| 车致| 安多县| 芦溪县| 三河市| 临潭县| 日照市| 彭阳县| 温州市| 且末县| 黎城县| 淅川县| 达孜县| 花莲县| 屏东市| 卓资县| 乌兰察布市| 海盐县| 江都市| 兴安县| 高要市| 南郑县| 襄樊市| 开封市| 忻城县| 利津县| 武清区|