从头认识java-18.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 + ") ";
} @Override
public 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 + ") ";
} @Override
public 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 + ") ";
} @Override
public 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 + ") ";
} @Override
public 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 + ") ";
} @Override
public 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多线程系列六、线程池
一. 线程池简介 1. 线程池的概念: 线程池就是首先创建一些线程,它们的集合称为线程池. 2. 使用线程池的好处 a) 降低资源的消耗.使用线程池不用频繁的创建线程和销毁线程 b) 提高响应速度,任 ...
- java多线程面试题_线程并发面试题
1.什么是线程?线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理器编程,你可以使用多线程对运算密集型任务提速.比如,如果一个线程完成一个 ...
- Java(279-298)【异常、线程】
1.异常的概念&异常的体系 异常,就是不正常的意思.在生活中:医生说,你的身体某个部位有异常,该部位和正常相比有点不同,该部位的功能将 受影响.在程序中的意思就是: 异常 :指的是程序在执行过 ...
- Java中的进程和线程
Java中的进程与线程 一:进程与线程 概述:几乎任何的操作系统都支持运行多个任务,通常一个任务就是一个程序,而一个程序就是一个进程.当一个进程运行时,内部可能包括多个顺序执行流,每个顺序执行流就是 ...
- Java中的进程与线程(总结篇)
详细文档: Java中的进程与线程.rar 474KB 1/7/2017 6:21:15 PM 概述: 几乎任何的操作系统都支持运行多个任务,通常一个任务就是一个程序,而一个程序就是一个进程.当一个进 ...
- 0036 Java学习笔记-多线程-创建线程的三种方式
创建线程 创建线程的三种方式: 继承java.lang.Thread 实现java.lang.Runnable接口 实现java.util.concurrent.Callable接口 所有的线程对象都 ...
- 转:Java Web应用中调优线程池的重要性
不论你是否关注,Java Web应用都或多或少的使用了线程池来处理请求.线程池的实现细节可能会被忽视,但是有关于线程池的使用和调优迟早是需要了解的.本文主要介绍Java线程池的使用和如何正确的配置线程 ...
- Java学习笔记-多线程-创建线程的方式
创建线程 创建线程的方式: 继承java.lang.Thread 实现java.lang.Runnable接口 所有的线程对象都是Thead及其子类的实例 每个线程完成一定的任务,其实就是一段顺序执行 ...
- java查看当前项目所有线程列表界面
java查看当前项目所有线程列表界面 1.TestThread(测试类) package com.isoftstone.pcis.isc.job.king.panel; public class Te ...
- java多线程详解(7)-线程池的使用
在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, 这样频繁创建线程就会大大降低系 ...
随机推荐
- C# 实体集合和实体转换成相应的string、XDocument、XElement、XDocument
https://msdn.microsoft.com/zh-cn/library/system.xml.linq.xelement(v=vs.110).aspx XElement.Parse 方法 ( ...
- 如何用php启动exe程序,并在进程中查看?
function query_process($service) { /* **查看WINDOWS系统进程列表,并查找指定进程是否存在 */ $tasklist = $_SERVER["WI ...
- unity, editorWindow lose data when enter play mode
我写了个editorWindow,其中有个成员变量m_x,在创建editorWindow的时候为m_x赋的值,而在editorWindow的OnGUI里把m_x显示出来. 当我开着这个editorWi ...
- Spring Cloud(九):分布式配置中心和消息总线
我们在Spring Cloud(七):使用SVN存储分布式配置中心文件和实现refresh中讲到,如果需要客户端获取到最新的配置信息需要执行refresh,我们可以利用webhook的机制每次提交代码 ...
- pow(x,y)函数的实现算法(递归函数)
函数pow(x,y)实现运算x^y,即x的y次方,这里x和y都为整数. 算法的基本思想是,减少乘法次数,重复利用结算结果,例如: x^4,如果逐个相乘的话,需要四次乘法.如果我们这样分解(x^2)*( ...
- [svc]visio绘制模具
visio2016狮子XL自定义运维模具下载: https://github.com/lannyMa/scripts/blob/master/%E7%BE%8E%E5%8C%96%E5%AE%9A%E ...
- EditText禁止输空格
1.EditText禁止输空格 editText.setFilters(new InputFilter[]{filter}); private InputFilter filter=new Input ...
- redis基础之安装和配置(一)
前言 折腾一下redis在linux环境的安装. ubantu16.04环境下安装 下载安装,依次执行命令; # 从官方网站下载安装包,注意,当前在哪个目录下执行命令,下载的包将在哪个目录下 $ wg ...
- linux下tar.gz、tar、bz2、zip等解压缩、压缩命令小结(转载)
Linux下最常用的打包程序就是tar了,使用tar程序打出来的包我们常称为tar包,tar包文件的命令通常都是以.tar结尾的.生成tar包后,就可以用其它的程序来进 行压缩了,所以首先就来讲讲ta ...
- 插入节点insertBefore()
http://www.imooc.com/code/1699 插入节点insertBefore() insertBefore() 方法可在已有的子节点前插入一个新的子节点. 语法: insertBef ...