Java編程中線程池的基本概念和使用
1 引入線程池的原因
由于線程的生命周期中包括創(chuàng)建、就緒、運(yùn)行、阻塞、銷(xiāo)毀階段,當(dāng)我們待處理的任務(wù)數(shù)目較小時(shí),我們可以自己創(chuàng)建幾個(gè)線程來(lái)處理相應(yīng)的任務(wù),但當(dāng)有大量的任務(wù)時(shí),由于創(chuàng)建、銷(xiāo)毀線程需要很大的開(kāi)銷(xiāo),運(yùn)用線程池這些問(wèn)題就大大的緩解了。
2 線程池的使用
我們只需要運(yùn)用Executors類(lèi)給我們提供的靜態(tài)方法,就可以創(chuàng)建相應(yīng)的線程池:
public static ExecutorSevice newSingleThreadExecutor() public static ExecutorSevice newFixedThreadPool() public static ExecutorSevice newCachedThreadPool()
newSingleThreadExecutor返回以個(gè)包含單線程的Executor,將多個(gè)任務(wù)交給此Exector時(shí),這個(gè)線程處理完一個(gè)任務(wù)后接著處理下一個(gè)任務(wù),若該線程出現(xiàn)異常,將會(huì)有一個(gè)新的線程來(lái)替代。
newFixedThreadPool返回一個(gè)包含指定數(shù)目線程的線程池,如果任務(wù)數(shù)量多于線程數(shù)目,那么沒(méi)有沒(méi)有執(zhí)行的任務(wù)必須等待,直到有任務(wù)完成為止。
newCachedThreadPool根據(jù)用戶的任務(wù)數(shù)創(chuàng)建相應(yīng)的線程來(lái)處理,該線程池不會(huì)對(duì)線程數(shù)目加以限制,完全依賴于JVM能創(chuàng)建線程的數(shù)量,可能引起內(nèi)存不足。
我們只需要將待執(zhí)行的任務(wù)放入run方法中即可,將Runnable接口的實(shí)現(xiàn)類(lèi)交給線程池的execute方法,作為它的一個(gè)參數(shù),如下所示:
Executor executor = Executors.newSingleThreadExecutor(); executor.execute(new Runnable(){ public void run(){ //執(zhí)行的任務(wù) } }
如果需要給任務(wù)傳遞參數(shù),可以通過(guò)創(chuàng)建一個(gè)Runnable接口的實(shí)現(xiàn)類(lèi)來(lái)完成。
3.實(shí)例
(1):newSingleThreadExecutor
MyThread.java
publicclassMyThread extends Thread { @Override publicvoid run() { System.out.println(Thread.currentThread().getName() + "正在執(zhí)行。。。"); } } TestSingleThreadExecutor.java publicclassTestSingleThreadExecutor { publicstaticvoid main(String[] args) { //創(chuàng)建一個(gè)可重用固定線程數(shù)的線程池 ExecutorService pool = Executors. newSingleThreadExecutor(); //創(chuàng)建實(shí)現(xiàn)了Runnable接口對(duì)象,Thread對(duì)象當(dāng)然也實(shí)現(xiàn)了Runnable接口 Thread t1 = new MyThread(); Thread t2 = new MyThread(); Thread t3 = new MyThread(); Thread t4 = new MyThread(); Thread t5 = new MyThread(); //將線程放入池中進(jìn)行執(zhí)行 pool.execute(t1); pool.execute(t2); pool.execute(t3); pool.execute(t4); pool.execute(t5); //關(guān)閉線程池 pool.shutdown(); } }
輸出結(jié)果
pool-1-thread-1正在執(zhí)行。。。 pool-1-thread-1正在執(zhí)行。。。 pool-1-thread-1正在執(zhí)行。。。 pool-1-thread-1正在執(zhí)行。。。 pool-1-thread-1正在執(zhí)行。。。
(2):newFixedThreadPool
TestFixedThreadPool.Java
publicclass TestFixedThreadPool { publicstaticvoid main(String[] args) { //創(chuàng)建一個(gè)可重用固定線程數(shù)的線程池 ExecutorService pool = Executors.newFixedThreadPool(2); //創(chuàng)建實(shí)現(xiàn)了Runnable接口對(duì)象,Thread對(duì)象當(dāng)然也實(shí)現(xiàn)了Runnable接口 Thread t1 = new MyThread(); Thread t2 = new MyThread(); Thread t3 = new MyThread(); Thread t4 = new MyThread(); Thread t5 = new MyThread(); //將線程放入池中進(jìn)行執(zhí)行 pool.execute(t1); pool.execute(t2); pool.execute(t3); pool.execute(t4); pool.execute(t5); //關(guān)閉線程池 pool.shutdown(); } }
輸出結(jié)果
pool-1-thread-1正在執(zhí)行。。。 pool-1-thread-2正在執(zhí)行。。。 pool-1-thread-1正在執(zhí)行。。。 pool-1-thread-2正在執(zhí)行。。。 pool-1-thread-1正在執(zhí)行。。。
(3): newCachedThreadPool
TestCachedThreadPool.java
publicclass TestCachedThreadPool { publicstaticvoid main(String[] args) { //創(chuàng)建一個(gè)可重用固定線程數(shù)的線程池 ExecutorService pool = Executors.newCachedThreadPool(); //創(chuàng)建實(shí)現(xiàn)了Runnable接口對(duì)象,Thread對(duì)象當(dāng)然也實(shí)現(xiàn)了Runnable接口 Thread t1 = new MyThread(); Thread t2 = new MyThread(); Thread t3 = new MyThread(); Thread t4 = new MyThread(); Thread t5 = new MyThread(); //將線程放入池中進(jìn)行執(zhí)行 pool.execute(t1); pool.execute(t2); pool.execute(t3); pool.execute(t4); pool.execute(t5); //關(guān)閉線程池 pool.shutdown(); } }
輸出結(jié)果:
pool-1-thread-2正在執(zhí)行。。。 pool-1-thread-4正在執(zhí)行。。。 pool-1-thread-3正在執(zhí)行。。。 pool-1-thread-1正在執(zhí)行。。。 pool-1-thread-5正在執(zhí)行。。。
(4):newScheduledThreadPool
TestScheduledThreadPoolExecutor.java
publicclass TestScheduledThreadPoolExecutor { publicstaticvoid main(String[] args) { ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1); exec.scheduleAtFixedRate(new Runnable() {//每隔一段時(shí)間就觸發(fā)異常 @Override publicvoid run() { //throw new RuntimeException(); System.out.println("================"); } }, 1000, 5000, TimeUnit.MILLISECONDS); exec.scheduleAtFixedRate(new Runnable() {//每隔一段時(shí)間打印系統(tǒng)時(shí)間,證明兩者是互不影響的 @Override publicvoid run() { System.out.println(System.nanoTime()); } }, 1000, 2000, TimeUnit.MILLISECONDS); } }
輸出結(jié)果
================ 8384644549516 8386643829034 8388643830710 ================ 8390643851383 8392643879319 8400643939383
相關(guān)文章
詳解如何使用MongoDB+Springboot實(shí)現(xiàn)分布式ID的方法
這篇文章主要介紹了詳解如何使用MongoDB+Springboot實(shí)現(xiàn)分布式ID的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09SpringBoot開(kāi)發(fā)之整合Mybatis詳解
這篇文章主要介紹了SpringBoot開(kāi)發(fā)之整合Mybatis詳解,MyBatis是一個(gè)半自動(dòng)的ORM框架,它允許我們通過(guò)編寫(xiě)SQL語(yǔ)句來(lái)操作數(shù)據(jù)庫(kù),使用MyBatis,我們可以通過(guò)定義映射文件(XML文件)或使用注解的方式將Java對(duì)象與數(shù)據(jù)庫(kù)表進(jìn)行映射,需要的朋友可以參考下2023-09-09Springboot2.x結(jié)合Mabatis3.x下Hikari連接數(shù)據(jù)庫(kù)報(bào)超時(shí)錯(cuò)誤
本文針對(duì)Springboot2.x與Mybatis3.x結(jié)合使用時(shí),Hikari連接數(shù)據(jù)庫(kù)出現(xiàn)超時(shí)錯(cuò)誤的問(wèn)題進(jìn)行了深入分析,并提供了一系列有效的解決方法,感興趣的可以了解一下2023-11-11spring-boot集成spring-security的oauth2實(shí)現(xiàn)github登錄網(wǎng)站的示例
本篇文章主要介紹了spring-boot集成spring-security的oauth2實(shí)現(xiàn)github登錄網(wǎng)站的示例,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-10-10使用Rhino讓java執(zhí)行javascript的方法實(shí)例
這篇文章主要介紹了java使用Rhino執(zhí)行javascript的方法,Rhino由Mozilla開(kāi)發(fā),是 JavaScript 一種基于Java的實(shí)現(xiàn)2013-12-12