摘要:四種線程池的使用介紹的弊端及四種線程池的使用,線程池的作用線程池作用就是限制系統中執行線程的數量。相比,提供的四種線程池的好處在于重用存在的線程,減少對象創建消亡的開銷,性能佳。延遲執行描述創建一個定長線程池,支持定時及周期性任務執行。
java 四種線程池的使用
介紹new Thread的弊端及Java四種線程池的使用
1,線程池的作用線程池作用就是限制系統中執行線程的數量。
根據系統的環境情況,可以自動或手動設置線程數量,達到運行的最佳效果。
少了浪費了系統資源,多了造成系統擁擠效率不高。
用線程池控制線程數量,其他線程排 隊等候。
一個任務執行完畢,再從隊列的中取最前面的任務開始執行。
若隊列中沒有等待進程,線程池的這一資源處于等待。
當一個新任務需要運行時,如果線程池 中有等待的工作線程,就可以開始運行了;否則進入等待隊列。
1.減少了創建和銷毀線程的次數,每個工作線程都可以被重復利用,可執行多個任務。
2.可以根據系統的承受能力,調整線程池中工作線線程的數目,防止因為消耗過多的內存,而把服務器累趴下(每個線程需要大約1MB內存,線程開的越多,消耗的內存也就越大,最后死機)。
Java里面線程池的頂級接口是Executor,但是嚴格意義上講Executor并不是一個線程池,而只是一個執行線程的工具。真正的線程池接口是ExecutorService。
3,比較重要的幾個類類 | 描述 |
---|---|
ExecutorService | 真正的線程池接口。 |
ScheduledExecutorService | 能和Timer/TimerTask類似,解決那些需要任務重復執行的問題。 |
ThreadPoolExecutor | ExecutorService的默認實現。 |
ScheduledThreadPoolExecutor | 繼承ThreadPoolExecutor的ScheduledExecutorService接口實現,周期性任務調度的類實現。 |
public class TestNewThread { public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { System.out.println("start"); } }).start(); } }
執行一個異步任務你還只是如下new Thread嗎?
那你就out太多了,new Thread的弊端如下:
1.每次new Thread新建對象性能差。
2.線程缺乏統一管理,可能無限制新建線程,相互之間競爭,及可能占用過多系統資源導致死機或oom。
3.缺乏更多功能,如定時執行、定期執行、線程中斷。
相比new Thread,Java提供的四種線程池的好處在于:
1.重用存在的線程,減少對象創建、消亡的開銷,性能佳。
2.可有效控制最大并發線程數,提高系統資源的使用率,同時避免過多資源競爭,避免堵塞。
3.提供定時執行、定期執行、單線程、并發數控制等功能。
Java通過Executors提供四種線程池,分別為:
1,newCachedThreadPoo創建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閑線程,若無可回收,則新建線程。
2,newFixedThreadPool創建一個定長線程池,可控制線程最大并發數,超出的線程會在隊列中等待。
3,newScheduledThreadPool創建一個定長線程池,支持定時及周期性任務執行。
4,newSingleThreadExecutor創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行。
示例 1,newCachedThreadPool創建一個可緩存的線程池。如果線程池的大小超過了處理任務所需要的線程, 那么就會回收部分空閑(60秒不執行任務)的線程,當任務數增加時,此線程池又可以智能的添加新線程來處理任務。此線程池不會對線程池大小做限制,線程池大小完全依賴于操作系統(或者說JVM)能夠創建的最大線程大小。
package io.ymq.thread.demo1; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 描述: 創建一個可緩存的線程池。如果線程池的大小超過了處理任務所需要的線程,那么就會回收部分空閑(60秒不執行任務)的線程,當任務數增加時,此線程池又可以智能的添加新線程來處理任務。 * 此線程池不會對線程池大小做限制,線程池大小完全依賴于操作系統(或者說JVM)能夠創建的最大線程大小。 * * @author yanpenglei * @create 2017-10-12 11:13 **/ public class TestNewCachedThreadPool { public static void main(String[] args) { ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); for (int i = 1; i <= 10; i++) { final int index = i; try { Thread.sleep(index * 1000); } catch (InterruptedException e) { e.printStackTrace(); } cachedThreadPool.execute(new Runnable() { @Override public void run() { String threadName = Thread.currentThread().getName(); System.out.println("執行:" + index + ",線程名稱:" + threadName); } }); } } }
響應:
執行:1,線程名稱:pool-1-thread-1 執行:2,線程名稱:pool-1-thread-1 執行:3,線程名稱:pool-1-thread-1 執行:4,線程名稱:pool-1-thread-1 執行:5,線程名稱:pool-1-thread-1 執行:6,線程名稱:pool-1-thread-1 執行:7,線程名稱:pool-1-thread-1 執行:8,線程名稱:pool-1-thread-1 執行:9,線程名稱:pool-1-thread-1 執行:10,線程名稱:pool-1-thread-12,newFixedThreadPool
描述:創建固定大小的線程池。每次提交一個任務就創建一個線程,直到線程達到線程池的最大大小。
線程池的大小一旦達到最大值就會保持不變,如果某個線程因為執行異常而結束,那么線程池會補充一個新線程。
package io.ymq.thread.demo2; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 描述:創建固定大小的線程池。每次提交一個任務就創建一個線程,直到線程達到線程池的最大大小。 * 線程池的大小一旦達到最大值就會保持不變,如果某個線程因為執行異常而結束,那么線程池會補充一個新線程。 * * @author yanpenglei * @create 2017-10-12 11:30 **/ public class TestNewFixedThreadPool { public static void main(String[] args) { ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3); for (int i = 1; i <= 10; i++) { final int index = i; fixedThreadPool.execute(new Runnable() { @Override public void run() { try { String threadName = Thread.currentThread().getName(); System.out.println("執行:" + index + ",線程名稱:" + threadName); Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } }); } } }
因為線程池大小為3,每個任務輸出index后sleep 2秒,所以每兩秒打印3個數字,和線程名稱。
響應:
執行:2,線程名稱:pool-1-thread-2 執行:3,線程名稱:pool-1-thread-3 執行:1,線程名稱:pool-1-thread-1 執行:4,線程名稱:pool-1-thread-1 執行:6,線程名稱:pool-1-thread-2 執行:5,線程名稱:pool-1-thread-3 執行:7,線程名稱:pool-1-thread-1 執行:9,線程名稱:pool-1-thread-3 執行:8,線程名稱:pool-1-thread-2 執行:10,線程名稱:pool-1-thread-13,newScheduledThreadPool
創建一個定長線程池,支持定時及周期性任務執行。延遲執行
package io.ymq.thread.demo3; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * 描述:創建一個定長線程池,支持定時及周期性任務執行。延遲執行 * * @author yanpenglei * @create 2017-10-12 11:53 **/ public class TestNewScheduledThreadPool { public static void main(String[] args) { ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5); scheduledThreadPool.schedule(new Runnable() { @Override public void run() { System.out.println("表示延遲3秒執行。"); } }, 3, TimeUnit.SECONDS); scheduledThreadPool.scheduleAtFixedRate(new Runnable() { @Override public void run() { System.out.println("表示延遲1秒后每3秒執行一次。"); } }, 1, 3, TimeUnit.SECONDS); } }
表示延遲1秒后每3秒執行一次。 表示延遲3秒執行。 表示延遲1秒后每3秒執行一次。 表示延遲1秒后每3秒執行一次。 表示延遲1秒后每3秒執行一次。 表示延遲1秒后每3秒執行一次。4,newSingleThreadExecutor
創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行。
package io.ymq.thread.demo4; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 描述:創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行。 * * @author yanpenglei * @create 2017-10-12 12:05 **/ public class TestNewSingleThreadExecutor { public static void main(String[] args) { ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); for (int i = 1; i <= 10; i++) { final int index = i; singleThreadExecutor.execute(new Runnable() { @Override public void run() { try { String threadName = Thread.currentThread().getName(); System.out.println("執行:" + index + ",線程名稱:" + threadName); Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } }); } } }
結果依次輸出,相當于順序執行各個任務。
響應:
執行:1,線程名稱:pool-1-thread-1 執行:2,線程名稱:pool-1-thread-1 執行:3,線程名稱:pool-1-thread-1 執行:4,線程名稱:pool-1-thread-1 執行:5,線程名稱:pool-1-thread-1 執行:6,線程名稱:pool-1-thread-1 執行:7,線程名稱:pool-1-thread-1 執行:8,線程名稱:pool-1-thread-1 執行:9,線程名稱:pool-1-thread-1 執行:10,線程名稱:pool-1-thread-1Contact
作者:鵬磊
出處:http://www.ymq.io
Email:admin@souyunku.com
版權歸作者所有,轉載請注明出處
Wechat:關注公眾號,搜云庫,專注于開發技術的研究與知識分享
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/67737.html
摘要:它是一種線程數量固定的線程池,當線程處于空閑狀態時,他們并不會被回收,除非線程池被關閉。這類線程池內部只有一個核心線程,它確保所有的任務都在同一個線程中按順序執行。 FixedThreadPool 由Executors的newFixedThreadPool方法創建。它是一種線程數量固定的線程池,當線程處于空閑狀態時,他們并不會被回收,除非線程池被關閉。當所有的線程都處于活動狀態時,新的...
摘要:此外,有兩個常用的關閉線程池的方法第一個方法將啟動一次順序關閉,有任務在執行,則等待執行完成,但不接受新的任務第二個方法將取消所有未開始的任務并且試圖中斷正在執行的任務,返回從未開始執行的任務的列表。 四種線程池 在Executors中提供了四種線程池: newCachedThreadPool 可緩存線程池,對于每個線程,如果有空閑線程可用,立即讓它執行,如果沒有,則創建一個新線...
摘要:當活動線程核心線程非核心線程達到這個數值后,后續任務將會根據來進行拒絕策略處理。線程池工作原則當線程池中線程數量小于則創建線程,并處理請求。當線程池中的數量等于最大線程數時默默丟棄不能執行的新加任務,不報任何異常。 spring-cache使用記錄 spring-cache的使用記錄,坑點記錄以及采用的解決方案 深入分析 java 線程池的實現原理 在這篇文章中,作者有條不紊的將 ja...
摘要:最后,我們會通過對源代碼的剖析深入了解線程池的運行過程和具體設計,真正達到知其然而知其所以然的水平。創建線程池既然線程池是一個類,那么最直接的使用方法一定是一個類的對象,例如。單線程線程池單線程線程 我們一般不會選擇直接使用線程類Thread進行多線程編程,而是使用更方便的線程池來進行任務的調度和管理。線程池就像共享單車,我們只要在我們有需要的時候去獲取就可以了。甚至可以說線程池更棒,...
摘要:創建方法最大線程數即源碼單線程化的線程池有且僅有一個工作線程執行任務所有任務按照指定順序執行,即遵循隊列的入隊出隊規則創建方法源碼還有一個結合了和,就不介紹了,基本不用。 *本篇文章已授權微信公眾號 guolin_blog (郭霖)獨家發布 為什么用線程池 創建/銷毀線程伴隨著系統開銷,過于頻繁的創建/銷毀線程,會很大程度上影響處理效率 >例如: > >記創建線程消耗時間T1,執行...
閱讀 2249·2021-09-23 11:52
閱讀 1915·2021-09-02 15:41
閱讀 3033·2019-08-30 10:47
閱讀 1997·2019-08-29 17:14
閱讀 2356·2019-08-29 16:16
閱讀 3200·2019-08-28 18:29
閱讀 3434·2019-08-26 13:30
閱讀 2619·2019-08-26 10:49