線程池詳細解析(未完成)

程序啓動一個新線程成本是比較高的,因爲它涉及到要與操作系統進行交互。而使用線程池可以很好的提高性能,尤其是當程序中要創建大量生存期很短的線程時,更應該考慮使用線程池。

線程池裏每一個線程代碼結束後,並不會死亡,而是再次回到線程池中成爲空閒狀態,等待下一個對象來使用。

線程池是一種多線程處理形式,處理過程中將任務添加隊列,然後在創建線程後自動啓動這些任務,每個線程都使用默認的堆棧大小,以默認的優先級運行,並處在多線程單元中,如果某個線程在託管代碼中空閒,則線程池將插入另一個輔助線程來使所有處理器保持繁忙。如果所有線程池都始終保持繁忙,但隊列中包含掛起的工作,則線程池將在一段時間後輔助線程的數目永遠不會超過最大值。超過最大值的線程可以排隊,但他們要等到其他線程完成後才能啓動。

java裏面的線程池的頂級接口是Executor,Executor並不是一個線程池,而只是一個執行線程的工具,而真正的線程池是ExecutorService

java中的有哪些線程池?

1.newCachedThreadPool創建一個可緩存線程池程

2.newFixedThreadPool 創建一個定長線程池

3.newSingleThreadExecutor 創建一個單線程化的線程池

4.newScheduledThreadPool 定時任務和具有固定週期

 

JDK5之後新增一個Executors工廠來生產線程池,有如下幾個方法

(1)public  static  ExecutorService  newCachedThreadPool()緩存60秒

是一種線程數量不定的線程池,並且其最大線程數爲Integer.MAX_VALUE,這個數是很大的,一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閒線程,若無可回收,則新建線程。但是線程池中的空閒線程都有超時限制,這個超時時長是60秒,超過60秒閒置線程就會被回收。調用execute將重用以前構造的線程(如果線程可用)。這類線程池比較適合執行大量的耗時較少的任務,當整個線程池都處於閒置狀態時,線程池中的線程都會超時被停止。

 

從結果可以看到,執行第二個任務的時候第一個任務已經完成,會複用執行第一個任務的線程,不用每次新建線程

(2)public  static  ExecutorService  newFixedThreadPool(int  nThreads)

創建一個指定工作線程數量的線程池,每當提交一個任務就創建一個工作線程,當線程處於空閒狀態時,它們並不會被回收,除非線程池被關閉了,如果工作線程數量達到線程池初始的最大數,則將提交的任務存入到池隊列(沒有大小限制)中。由於newFixedThreadPool只有核心線程並且這些核心線程不會被回收,這樣它更加快速底相應外界的請求

由於設置最大線程是3,所以當執行完這3個線程後,等待兩秒後,在執行後面4個線程。

(3)public  static  ExecutorService  newSingleThreadExecutor()

 這類線程池內部只有一個核心線程,以無界隊列方式來執行該線程,這使得這些任務之間不需要處理線程同步的問題,它確保所有的任務都在同一個線程中按順序中執行,並且可以在任意給定的時間不會有多個線程是活動的。

可發現是有順序地去執行上面6個線程。

(4)public  static  ExecutorService  newScheduledThreadPool ()

創建一個線程池,它的核心線程數量是固定的,而非核心線程數是沒有限制的,並且當非核心線程閒置時會被立即回收,它可安排給定延遲後運行命令或者定期地執行。這類線程池主要用於執行定時任務和具有固定週期的重複任務

誤差可以忽略,實際結果確實延遲了4秒執行。

可發現確實延遲2秒後每隔3秒後就會執行一次,程序不退出就一直執行下去

 

這些方法的返回值是ExecutorService對象,該對象表示一個線程池,可以執行Runnable對象或者Callable對象代表的線程。它提供瞭如下方法

Future<?>  submit(Runnable  task)

<T> Future<T>  submit(Callable<T> task)

案例提示

創建線程池對象

創建Runnable實例

提交Runnable實例

關閉線程池

線程池的好處:線程池裏的每一個線程代碼結束後,並不會死亡,而是再次回到線程池中成爲空閒狀態,等待下一個對象來使用。

3.使用線程池的優點

1.重用線程池的線程,避免因爲線程的創建和銷燬鎖帶來的性能開銷

2.有效控制線程池的最大併發數,避免大量的線程之間因搶佔系統資源而阻塞

3.能夠對線程進行簡單的管理,並提供一下特定的操作如:可以提供定時、定期、單線程、併發數控制等功能

 * 如何實現線程的代碼呢?

 * A:創建一個線程池對象,控制要創建幾個線程對象。

public static ExecutorService newFixedThreadPool(int nThreads)

 * B:這種線程池的線程可以執行:

 * 可以執行Runnable對象或者Callable對象代表的線程

 * 做一個類實現Runnable接口。

 * C:調用如下方法即可

 * Future<?> submit(Runnable task)

 * <T> Future<T> submit(Callable<T> task)

 * D:我就要結束線程池,可以嗎?

 * 可以。 pool.shutdown()

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