線程池的概念:
線程池就是首先創(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)資源,以及過渡切換線程的危險,從而可能導致系統(tǒng)資源的崩潰。這時,線程池就是最好的選擇了。
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)完成,會復用執(zhí)行上一個任務(wù)的線程,而不用每次新建線程
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. }
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. }
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. }