從頭認識java-17.2 基本的線程機制(2)-Executors的使用

來源:互聯網
上載者:User

從頭認識java-17.2 基本的線程機制(2)-Executors的使用

在前面的章節我們都是直接對Thread進行管理,我們這裡解釋一下另一個管理Thread的類Executors。

1.例子:

package com.ray.ch17;import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class Test {public static void main(String[] args) throws InterruptedException {long startTime = System.currentTimeMillis();ExecutorService executorService = Executors.newCachedThreadPool();CountDownLatch countDownLatch = new CountDownLatch(5);for (int i = 5; i < 10; i++) {DoneMission doneMission = new DoneMission(i, countDownLatch);executorService.execute(doneMission);}executorService.shutdown();countDownLatch.await();long endTime = System.currentTimeMillis();System.out.println();System.out.println(endTime - startTime);}}class DoneMission implements Runnable {private final int id = index++;private int count = 0;private static int index = 0;private CountDownLatch countDownLatch;public DoneMission(int count, CountDownLatch countDownLatch) {this.count = count;this.countDownLatch = countDownLatch;}public String leftMission() {return "#" + id + "(" + count + ") ";}@Overridepublic void run() {while (count-- > 0) {System.out.print(leftMission());try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}Thread.yield();}countDownLatch.countDown();}}

 

 

解釋:

(1)運行任務的類跟前面的基本一致

(2)使用Executors.newCachedThreadPool()產生線程池,當需要線程驅動的時候,我們可以到裡面拿,它產生的線程數是有系統控制的。

 

2.對線程的數量做出控制

 

package com.ray.ch17;import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class Test {public static void main(String[] args) throws InterruptedException {long startTime = System.currentTimeMillis();ExecutorService executorService = Executors.newFixedThreadPool(5);//控制線程的數量CountDownLatch countDownLatch = new CountDownLatch(5);for (int i = 5; i < 10; i++) {DoneMission doneMission = new DoneMission(i, countDownLatch);executorService.execute(doneMission);}executorService.shutdown();countDownLatch.await();long endTime = System.currentTimeMillis();System.out.println();System.out.println(endTime - startTime);}}class DoneMission implements Runnable {private final int id = index++;private int count = 0;private static int index = 0;private CountDownLatch countDownLatch;public DoneMission(int count, CountDownLatch countDownLatch) {this.count = count;this.countDownLatch = countDownLatch;}public String leftMission() {return "#" + id + "(" + count + ") ";}@Overridepublic void run() {while (count-- > 0) {System.out.print(leftMission());try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}Thread.yield();}countDownLatch.countDown();}}

上面的代碼只是替換了一句,就可以控制線程的數量,但是我們一般還是建議使用cache的那個,因為它對線程池做出來最佳化。特別是對於短的非同步任務它具有明顯優勢。

 

 

3.測試不同線程啟動並執行時間:

 

package com.ray.ch17;import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class Test {public static void main(String[] args) throws InterruptedException {long startTime = System.currentTimeMillis();ExecutorService executorService = Executors.newCachedThreadPool();CountDownLatch countDownLatch = new CountDownLatch(5);for (int i = 5; i < 10; i++) {DoneMission doneMission = new DoneMission(i, countDownLatch);executorService.execute(doneMission);}executorService.shutdown();countDownLatch.await();long endTime = System.currentTimeMillis();System.out.println();System.out.println("time:"+(endTime - startTime));}}class DoneMission implements Runnable {private final int id = index++;private int count = 0;private static int index = 0;private CountDownLatch countDownLatch;public DoneMission(int count, CountDownLatch countDownLatch) {this.count = count;this.countDownLatch = countDownLatch;}public String leftMission() {return "#" + id + "(" + count + ") ";}@Overridepublic void run() {while (count-- > 0) {System.out.print(leftMission());try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}Thread.yield();}countDownLatch.countDown();}}

輸出:

 

#0(4) #1(5) #2(6) #3(7) #4(8) #0(3) #1(4) #4(7) #3(6) #2(5) #0(2) #1(3) #3(5) #2(4) #4(6) #0(1) #1(2) #4(5) #3(4) #2(3) #0(0) #1(1) #2(2) #4(4) #3(3) #1(0) #2(1) #3(2) #4(3) #4(2) #3(1) #2(0) #3(0) #4(1) #4(0)
904

 

控製為3個線程:

 

package com.ray.ch17;import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class Test {public static void main(String[] args) throws InterruptedException {long startTime = System.currentTimeMillis();ExecutorService executorService = Executors.newFixedThreadPool(3);CountDownLatch countDownLatch = new CountDownLatch(5);for (int i = 5; i < 10; i++) {DoneMission doneMission = new DoneMission(i, countDownLatch);executorService.execute(doneMission);}executorService.shutdown();countDownLatch.await();long endTime = System.currentTimeMillis();System.out.println();System.out.println(endTime - startTime);}}class DoneMission implements Runnable {private final int id = index++;private int count = 0;private static int index = 0;private CountDownLatch countDownLatch;public DoneMission(int count, CountDownLatch countDownLatch) {this.count = count;this.countDownLatch = countDownLatch;}public String leftMission() {return "#" + id + "(" + count + ") ";}@Overridepublic void run() {while (count-- > 0) {System.out.print(leftMission());try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}Thread.yield();}countDownLatch.countDown();}}

輸出:

 

#0(4) #2(6) #1(5) #1(4) #0(3) #2(5) #0(2) #2(4) #1(3) #1(2) #2(3) #0(1) #0(0) #1(1) #2(2) #1(0) #2(1) #3(7) #3(6) #4(8) #2(0) #3(5) #4(7) #3(4) #4(6) #3(3) #4(5) #4(4) #3(2) #4(3) #3(1) #4(2) #3(0) #4(1) #4(0)
1504

 

控製為單線程:

 

package com.ray.ch17;import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class Test {public static void main(String[] args) throws InterruptedException {long startTime = System.currentTimeMillis();ExecutorService executorService = Executors.newSingleThreadExecutor();CountDownLatch countDownLatch = new CountDownLatch(5);for (int i = 5; i < 10; i++) {DoneMission doneMission = new DoneMission(i, countDownLatch);executorService.execute(doneMission);}executorService.shutdown();countDownLatch.await();long endTime = System.currentTimeMillis();System.out.println();System.out.println(endTime - startTime);}}class DoneMission implements Runnable {private final int id = index++;private int count = 0;private static int index = 0;private CountDownLatch countDownLatch;public DoneMission(int count, CountDownLatch countDownLatch) {this.count = count;this.countDownLatch = countDownLatch;}public String leftMission() {return "#" + id + "(" + count + ") ";}@Overridepublic void run() {while (count-- > 0) {System.out.print(leftMission());try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}Thread.yield();}countDownLatch.countDown();}}

輸出:

 

#0(4) #0(3) #0(2) #0(1) #0(0) #1(5) #1(4) #1(3) #1(2) #1(1) #1(0) #2(6) #2(5) #2(4) #2(3) #2(2) #2(1) #2(0) #3(7) #3(6) #3(5) #3(4) #3(3) #3(2) #3(1) #3(0) #4(8) #4(7) #4(6) #4(5) #4(4) #4(3) #4(2) #4(1) #4(0)
3503

單線程說白了就像直接在main方法裡面使用for來啟動並執行一樣。 

4.關於shutdown()(下面的這段話摘自http://my.oschina.net/bairrfhoinn/blog/177639,筆者覺得他解釋的已經比較清楚,其實關鍵是筆者比較懶,不喜歡打字)

為了關閉在 ExecutorService 中的線程,你需要調用 shutdown() 方法。ExecutorService 並不會馬上關閉,而是不再接收新的任務,一旦所有的線程結束執行當前任務,ExecutorServie 才會真的關閉。所有在調用 shutdown() 方法之前提交到 ExecutorService 的任務都會執行。
如果你希望立即關閉 ExecutorService,你可以調用 shutdownNow() 方法。這個方法會嘗試馬上關閉所有正在執行的任務,並且跳過所有已經提交但是還沒有啟動並執行任務。但是對於正在執行的任務,是否能夠成功關閉它是無法保證的,有可能他們真的被關閉掉了,也有可能它會一直執行到任務結束。

總結:這一章節主要介紹Executors的使用。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.