您好,登錄后才能下訂單哦!
這篇文章主要講解了“java中ThreadPoolExecutor的使用方法”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“java中ThreadPoolExecutor的使用方法”吧!
ThreadPoolExecutor也就是線程池。它就是Java為我們開發多線程程序時提供的一個開發框架。它可以統一的管理線程的創建、銷毀、優化、監控等,在使用線程池時比我們直接使用原始的線程類更加方便。既然線程池這么方便,那它到底是怎么實現上述的功能呢?下面我們先看一下當用線程池啟動一個線程時它的流程圖。
線程池的處理流程如下:
當我們用線程池啟動一個任務時,線程池首先會檢查核心線程池里面的線程數是否已經超過corePoolSize。如果沒有超過則創建一個新的線程執行任務。如果超過了,那么將當前執行的任務添加到線程池的工作隊列中,但在加入之前會先檢查工作隊列是否已經滿了,如果工作隊列已經滿了,那么此時它會檢查線程池中的線程是否超過了允許的最大數量。如果沒有超過則創建線程執行任務,如果超過了最大數量,則按照無法執行的策略處理。
線程池的創建:在創建ThreadPoolExecutor時,會需要傳遞幾個必要的參數,下面我們詳細看一下它們每個參數所代表的含義。
corePoolSize(初始化的空閑線程):當我們創建ThreadPoolExecutor對象時,可以用corePoolSize參數設置線程池的初始化線程數,也就是空閑線程,當線程池中的線程數量小于corePoolSize時,線程池會重新創建一個新的線程來處理任務,而不是直接使用線程池中的空閑線程。
maximumPoolSize(線程池最大數量):線程池允許創建的最大線程數。也就最大并發數,也就是說線程池允許多少個線程同時執行。
keepAliveTime(線程活動保持時間):當線程池中的線程數大于corePoolSize時,用此參數設置空閑線程等待新任務的時間。在此時間內如果線程沒有接收到新的任務,那么當前線程會被銷毀。
TimeUnit(線程活動保持時間的單位):可選的單位有天(DAYS)、小時(HOURS)、分鐘(MINUTES)、毫秒(MILLISECONDS)、微秒(MICROSECONDS,千分之一毫秒)和納秒(NANOSECONDS,千分之一微秒)。
BlockingQueue(線程池中的任務隊列),當線程池中線程數大于corePoolSize時,新提交的任務會被保存到任務隊列中。在線程池中主要有4種不同的任務隊列。
ArrayBlockingQueue:是基于數組結構的任務隊列。此隊列按先進先出的原則對任務進行排序。
LinkedBlockingQueue:是基于鏈表結構的任務隊列。此隊列也是按先進先出的原則對任務進行排序。但性能通常要比ArrayBlockingQueue高
SynchronousQueue:一個不存儲元素的任務隊列。每個插入操作必須等到另一個線程調用移除操作,否則插入操作一直處于阻塞狀態。
PriorityBlockingQueue:是一個具有優先級的任務隊列。此隊列中的元素必須能夠比較。
ThreadFactory():創建線程的線程工廠。
RejectedExecutionHandler(飽和策略 ):當線程池中的線程數大于maximumPoolSize時,線程池就不能在處理任何任務了,這時線程池會拋出異常。原因就是這個策略默認情況下是AbortPolicy:表示無法處理新任務時拋出異常。除此之外還有其它幾種策略:
AbortPolicy:直接拋出異常。
CallerRunsPolicy:只用調用者所在線程來運行任務。
DiscardOldestPolicy:丟棄隊列里最近的一個任務,并執行當前任務。
DiscardPolicy:不處理,丟棄掉。
下面我們用具體的代碼來詳細說明一下ThreadPoolExecutor的使用。
按照上面的分析,因為我們創建ThreadPoolExecutor對象時初始化的空閑線程是2個,并且我們添加到線程池中的數量也是2個,所以當前任務是由核心線程池執行的任務并不會將任務添加到對列中。如果我在繼續向線程池中提交任務,那么因為超過了我們設置的corePoolSize數量,所以此時隊列中就有了我們新提交的任務了。
因為我們設置的線程池的最大線程數是3也就是maximumPoolSize的值。如果超過這個值,并且我們沒有更改相應的飽和策略,那么此時就會拋出異常信息。
我們發現程序居然沒有報錯,這是因為什么呢。這是因為參數maximumPoolSize的作是指線程池最大能允許的最大并發數是3也就是說同時可以執行3個線程,但是我們別忘了線程池中還有一個隊列呢。隊列里存儲的就是將要被執行的任務,只是現在已經超過了最大并發數所以隊列里的任務只能等待線程池中有其它任務執行完后,它才可以執行。所以此時線程池中允許我們提交任務的最大數就是maximumPoolSize加上隊列的數量。但如果我們繼續向線程池有添加任務,那么線程池就會報錯了,因為已經沒有地方存儲新任務了,隊列也已經滿了,所以只能走飽和策略的默認策略就是拋出異常。
下面我們修改一下線程池的飽和策略。
線程池中相關方法的介紹
taskCount:線程池需要執行的任務數。雖然我們向線程池中提交了5個任務,但第5個任務并不是由線程池執行的,是我們修改了飽和策略自己執行的。所以此值返回結果是4。
completedTaskCount:線程池中完成的任務數。
largestPoolSize:線程池中曾經創建過的最大線程數。也就是有多少個線程同是執行,也叫最大并發數。
getPoolSize:線程池中的線程數。如果線程池不銷毀,那么線程池里的線程也不會自動銷毀。
getActiveCount:活動的線程數。
感謝各位的閱讀,以上就是“java中ThreadPoolExecutor的使用方法”的內容了,經過本文的學習后,相信大家對java中ThreadPoolExecutor的使用方法這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。