从头认识java-18.2 基本的线程机制(2)-Executors的使用
来源:互联网 发布:网络为什么会连接超时 编辑:程序博客网 时间:2024/05/02 23:29
在前面的章节我们都是直接对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的使用。
这一章节就到这里,谢谢。
-----------------------------------
目录
- 从头认识java-18.2 基本的线程机制(2)-Executors的使用
- 从头认识java-18.2 基本的线程机制(1)-再识多线程-2
- 从头认识java-18.2 基本的线程机制(5)-守护线程与非守护线程
- 从头认识java-18.2 基本的线程机制(3)-线程的返回与sleep
- 从头认识java-18.2 基本的线程机制(8)多线程的异常捕捉
- 从头认识java-18.2 基本的线程机制(1)-再识多线程-1
- 从头认识java-18.2 基本的线程机制(4)-优先级
- 从头认识java-18.2 基本的线程机制(7)join
- 从头认识java-18.2 基本的线程机制(6)-使用构造器或者内部类来实现多线程的编码变体
- Java学习--线程池Executors的使用
- Java的Executors(线程池)使用
- JAVA线程池类Executors的使用
- Java Executors工具线程池的使用
- Java线程池Executors的使用
- Executors与ThreadPoolExecutor(阿里发布的 Java开发手册中强制线程池不允许使用 Executors 去创建)
- 从头认识java-11.5 扫描输入(2)-scanner的边界与使用正则表达式扫描
- 从头认识java-11.4 正则表达式(2)-基本语法
- java.util.concurrent包中线程池Executors的使用
- Android 经典蓝牙用法
- strlen与sizeof区别
- 华为机试——求数组中的第一大和第二大数
- socket编程(TCP、UDP)
- iOS Newbie - Xcode 7 & iOS 9 页面间传值
- 从头认识java-18.2 基本的线程机制(2)-Executors的使用
- 指针
- IOS开发~UISCrollView与UITableView嵌套使用终极解决方案
- Linux--ubuntu卸载gnome桌面
- github 命令学习
- 关于冒泡排序
- netty5源码分析(5)--学习笔记
- Android Fragment详解(一):概括
- c++学习之构造函数和析构函数篇