<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
什麼是執行緒池?
咱們也不看長篇大論,通俗的來講,執行緒池就是裝執行緒的容器,當需要用的時候去池裡面取出來,不用的時候放回去或者銷燬。這樣一個執行緒就可以反覆的利用,通過執行緒的這種反覆利用機制,可以有效地避免直接建立執行緒所帶來的壞處。
執行緒池有什麼好處?
執行緒池建立流程圖:
其實通過這個圖就可以看到執行緒池的處理過程:
先看一下官網給出的建立方法(部分):
完整的可以參考官方檔案:
https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/concurrent/Executors.html
這裡介紹四種常用的建立型別:
建立可快取的執行緒物件,意思是這個任務需要幾個執行緒來處理,就會建立幾個執行緒:
執行緒需要執行的類:
public class MyRunnable implements Runnable{ int num; public MyRunnable(int num) { this.num = num; } @Override public void run() { System.out.println(Thread.currentThread().getName()+"執行了:"+num); } }
測試類:
public class Test { public static void main(String[] args) { //建立單個執行緒池物件,裡面執行緒只有一個 ExecutorService cachedService = Executors.newCachedThreadPool(); //執行5個任務 for (int i = 1; i<= 5; i++) { cachedService.execute(new MyRunnable(i)); } } }
來看看結果:
OK,上述程式碼執行緒池用了5個執行緒來處理,那麼如果我們在每次執行前加一次執行緒休眠會怎麼樣? 在每次執行後需要休眠0.5秒(500毫秒):
public class Test { public static void main(String[] args) { //建立一個快取的執行緒池物件 ExecutorService cachedService = Executors.newCachedThreadPool(); for (int i = 1; i<= 5; i++) { cachedService.execute(new MyRunnable(i)); //執行緒休眠: try{ Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } } }
看看結果:
小結:
這個方法是建立只有一個執行緒的執行緒池,不管怎麼樣,多隻有一個執行緒來幫你執行任務:
public class Test { public static void main(String[] args) { //建立單個執行緒池物件,裡面執行緒只有一個 ExecutorService singleService = Executors.newSingleThreadExecutor(); //執行一百萬次任務 for (int i = 1; i<= 1000000; i++) { singleService.execute(new MyRunnable(i)); } } }
看看結果:
對吧,執行了1000000次也是一個執行緒在執行,因為這個執行緒池裡面只有一個執行緒呀。
這個方法就是建立固定執行緒數的執行緒池,比如我要一個這個池裡面有10個執行緒,在後面輸入引數即可:
public class Test { public static void main(String[] args) { //執行緒池建立固定數量的執行緒物件來執行任務,這裡建立10個執行緒物件,由執行緒池管理生命週期 ExecutorService singleService = Executors.newFixedThreadPool(10); //執行10個任務 for (int i = 1; i<= 100; i++) { singleService.execute(new MyRunnable(i)); } } }
看看結果:
建立一個固定長度的執行緒池,並且以延時或定時的方式來執行執行緒,也就是說使用這個方法建立的執行緒池可以自定義每次執行的時間:
Demo:
public class MyRunnable implements Runnable{ @Override public void run() { System.out.println(Thread.currentThread().getName()+"延遲5秒執行,並且每2秒執行一次該任務:"); } }
測試類:
public class Test { public static void main(String[] args) { //執行緒池建立一個定時任務的執行緒物件 ScheduledExecutorService service = Executors.newScheduledThreadPool(4); /** *定時器執行的任務,並且按週期執行 * 引數1:執行緒任務 * 引數2:5秒之後開始執行 * 引數3:執行後每2秒為一個週期去迴圈執行 * 引數4:時間單位。列舉型別,我這指定秒(可以參考API) */ service.scheduleAtFixedRate(new MyRunnable(),5,1, TimeUnit.SECONDS); } }
看看結果:
當以上四種執行緒池滿不足業務需求的時候,咱們也可以自定義執行緒池:
先來一個執行緒執行類:
public class MyRunnable implements Runnable{ int num; public MyRunnable(int i) { this.num = num; } @Override public void run() { System.out.println(Thread.currentThread().getName()+"執行了"+num); } }
測試類:
public class Test { public static void main(String[] args) { /** * 引數1:執行緒池有5個固定的執行緒物件 * 引數2:當執行緒池的執行緒忙不過來的時候,最大執行緒數為7,也就是說執行緒物件就可以增加到7個(其中2個是臨時執行緒) * 引數3:當臨時執行緒物件超出300毫秒的時候還沒有接到新任務,執行緒池就自動 銷燬臨時的執行緒物件 * 引數4:時間單位。這指定秒,具體參考TimeUnit的列舉型別 * 引數5:等待執行的任務序列4個(其中有4個任務序列等待執行緒池物件來執行任務) */ ThreadPoolExecutor executor = new ThreadPoolExecutor(5,7,300, TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(4)); for (int i = 0; i < 6; i++) { executor.execute(new MyRunnable(i)); showInfo(executor); } } //獲取執行緒的一些資訊 private static void showInfo(ThreadPoolExecutor executor) { System.out.println("執行緒池的總數量:"+executor.getPoolSize()); System.out.println("佇列中等待執行的任務數:"+executor.getQueue().size()); System.out.println("已經執行完畢的任務數:"+executor.getCompletedTaskCount()); System.out.println("---------"); } }
Runnable是不返還值的,而Callable可以返回值,具體可以看這篇部落格(其實主要我也沒深入學習這個哈哈): Runnable和Callable的區別
通過這個文章,咱們對執行緒池有了基礎的瞭解,如何去建立和使用,但這僅僅是最簡單的,執行緒是一個複雜的東西,大家也可以參考其他技術部落格來深入學習和研究,在建立執行緒池的時候,根據場景,合理設定執行緒池的各個引數,包括執行緒池數量、佇列、執行緒工廠和拒絕策略,讓資源更好的利用起來,這也是優化效能的關鍵。
到此這篇關於Java十分鐘入門多執行緒下篇的文章就介紹到這了,更多相關Java 多執行緒內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45