前言,對于Java程序猿來說,線程池是面試高頻題,是我們必須掌握的一個技能,本篇文章主要給大家講解四種線程池的使用。線程池簡介線程池的概念: 線程池就是首先創(chuàng)建一些線程,它們的集合稱為線程池。使用線程池可以很好地提高性能,線程池在系統(tǒng)啟動時即創(chuàng)建大量空閑的線程,程序?qū)⒁粋€任務(wù)傳給線程池,線程池就會啟動一條線程來執(zhí)行這個任務(wù),執(zhí)行結(jié)束以后,該線程并不會死亡,而是再次返回線程池中成為空閑狀態(tài),等待執(zhí)行下一個任務(wù)。 線程池的工作機制: 在線程池的編程模式下,任務(wù)是提交給整個線程池,而不是直接提交給某個線程,線程池在拿到任務(wù)后,就在內(nèi)部尋找是否有空閑的線程,如果有,則將任務(wù)交給某個空閑的線程。 一個線程同時只能執(zhí)行一個任務(wù),但可以同時向一個線程池提交多個任務(wù)。 使用線程池的原因: 多線程運行時間,系統(tǒng)不斷的啟動和關(guān)閉新線程,成本非常高,會過渡消耗系統(tǒng)資源,以及過渡切換線程的危險,從而可能導(dǎo)致系統(tǒng)資源的崩潰。這時,線程池就是最好的選擇了。 四種常見的線程池詳解4.1 Executors.newCacheThreadPool()Executors.newCacheThreadPool():可緩存線程池,先查看池中有沒有以前建立的線程,如果有,就直接使用。如果沒有,就建一個新的線程加入池中,緩存型池子通常用于執(zhí)行一些生存期很短的異步型任務(wù) 代碼: 1. import java.util.concurrent.ExecutorService; 2. import java.util.concurrent.Executors; 3. 4. public class ThreadPoolExecutorTest { 5. public static void main(String[] args) { 6. //創(chuàng)建一個可緩存線程池 7. ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); 8. for (int i = 0; i < 10; i++) { 9. try { 10. //sleep可明顯看到使用的是線程池里面以前的線程,沒有創(chuàng)建新的線程 11. Thread.sleep(1000); 12. } catch (InterruptedException e) { 13. e.printStackTrace(); 14. } 15. cachedThreadPool.execute(new Runnable() { 16. public void run() { 17. //打印正在執(zhí)行的緩存線程信息 18. System.out.println(Thread.currentThread().getName()+"正在被執(zhí)行"); 19. } 20. }); 21. } 22. } 23. } 線程池為無限大,當執(zhí)行當前任務(wù)時上一個任務(wù)已經(jīng)完成,會復(fù)用執(zhí)行上一個任務(wù)的線程,而不用每次新建線程 4.2 Executors.newFixedThreadPool(int n)Executors.newFixedThreadPool(int n):創(chuàng)建一個可重用固定個數(shù)的線程池,以共享的無界隊列方式來運行這些線程。 代碼: 1. package com.study.test; 2. 3. import java.util.concurrent.ExecutorService; 4. import java.util.concurrent.Executors; 5. 6. public class ThreadPoolExecutorTest { 7. public static void main(String[] args) { 8. //創(chuàng)建一個可重用固定個數(shù)的線程池 9. ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3); 10. for (int i = 0; i < 10; i++) { 11. fixedThreadPool.execute(new Runnable() { 12. public void run() { 13. try { 14. //打印正在執(zhí)行的緩存線程信息 15. System.out.println(Thread.currentThread().getName()+"正在被執(zhí)行"); 16. Thread.sleep(2000); 17. } catch (InterruptedException e) { 18. e.printStackTrace(); 19. } 20. } 21. }); 22. } 23. } 24. } 25. } 4.3 Executors.newScheduledThreadPool(int n)Executors.newScheduledThreadPool(int n):創(chuàng)建一個定長線程池,支持定時及周期性任務(wù)執(zhí)行 代碼: 1. package com.study.test; 2. 3. import java.util.concurrent.Executors; 4. import java.util.concurrent.ScheduledExecutorService; 5. import java.util.concurrent.TimeUnit; 6. 7. public class ThreadPoolExecutorTest { 8. public static void main(String[] args) { 9. //創(chuàng)建一個定長線程池,支持定時及周期性任務(wù)執(zhí)行——延遲執(zhí)行 10. ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5); 11. //延遲1秒執(zhí)行 12. scheduledThreadPool.schedule(new Runnable() { 13. public void run() { 14. System.out.println("延遲1秒執(zhí)行"); 15. } 16. }, 1, TimeUnit.SECONDS); 17. } 18. } 輸出結(jié)果:延遲1秒執(zhí)行 代碼2:可以定時執(zhí)行 1. package com.study.test; 2. 3. import java.util.concurrent.Executors; 4. import java.util.concurrent.ScheduledExecutorService; 5. import java.util.concurrent.TimeUnit; 6. 7. public class ThreadPoolExecutorTest { 8. public static void main(String[] args) { 9. //創(chuàng)建一個定長線程池,支持定時及周期性任務(wù)執(zhí)行——定期執(zhí)行 10. ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5); 11. //延遲1秒后每3秒執(zhí)行一次 12. scheduledThreadPool.scheduleAtFixedRate(new Runnable() { 13. public void run() { 14. System.out.println("延遲1秒后每3秒執(zhí)行一次"); 15. } 16. }, 1, 3, TimeUnit.SECONDS); 17. } 18. } 4.4 Executors.newSingleThreadExecutor()Executors.newSingleThreadExecutor():創(chuàng)建一個單線程化的線程池,它只會用唯一的工作線程來執(zhí)行任務(wù),保證所有任務(wù)按照指定順序(FIFO, LIFO, 優(yōu)先級)執(zhí)行。 1. package com.study.test; 2. 3. import java.util.concurrent.ExecutorService; 4. import java.util.concurrent.Executors; 5. 6. public class TestThreadPoolExecutor { 7. public static void main(String[] args) { 8. ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); 9. for (int i = 0; i < 10; i++) { 10. final int index = i; 11. singleThreadExecutor.execute(new Runnable() { 12. public void run() { 13. try { 14. //結(jié)果依次輸出,相當于順序執(zhí)行各個任務(wù) 15. System.out.println(Thread.currentThread().getName()+"正在被執(zhí)行,打印的值是:"+index); 16. Thread.sleep(1000); 17. } catch (InterruptedException e) { 18. e.printStackTrace(); 19. } 20. } 21. }); 22. } 23. } 24. } |
|
來自: 好程序員IT > 《Java培訓(xùn)教程》