从头认识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)-线程池的使用
在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, 这样频繁创建线程就会大大降低系 ...
随机推荐
- Servlet路径
这里仅限OSGi注册的Servlet,WebServer里面应该有所不同. http.registerServlet("/control/main", new ControlSer ...
- 基于Java的在线聊天室
概述 Java socket编程,实现一个在线聊天室, 实现在线用户群聊,私聊,发送文件等功能. 详细 代码下载:http://www.demodashi.com/demo/13623.html 一. ...
- iOS开发-多线程编程技术(Thread、Cocoa operations、GCD)
简介 在软件开发中,多线程编程技术被广泛应用,相信多线程任务对我们来说已经不再陌生了.有了多线程技术,我们可以同做多个事情,而不是一个一个任务地进行.比如:前端和后台作交互.大任务(需要耗费一定的时间 ...
- LaunchScreen.storyboard 设置图片后不显示(转)
LaunchScreen.storyboard 设置图片后不显示 将图片放在根目录下即可 3D85E99F-A79B-4419-817D-1417E1446624.png 转至:http://ww ...
- C++代码优化方法总结
C++代码优化方法总结 优化是一个非常大的主题,本文并不是去深入探讨性能分析理论,算法的效率,况且我也没有这个能力.我只是想把一些可以简单的应用到你的C++代码中 的优化技术总结在这里,这样,当你遇到 ...
- 我写的websocket推送例子,每隔5秒服务器向客户端浏览器发送消息(node.js和浏览器)
node.js服务端 先要安装ws模块的支持 npm install ws 服务端(server.js) var gws; var WebSocketServer = require('ws').Se ...
- 如何查看Linux操作系统的位数
如何查看Linux操作系统的位数 1.编程实现: 在程序中返回sizeof(int)的值,返回的结果是操作系统的字节数.若返回4则是32位操作系统,返回8即是64位. 2.2.getconf命令: g ...
- jmx 配置
1.启动添加jmx参数 -Dcom.sun.management.jmxremote.port=8999 -Dcom.sun.management.jmxremote.ssl=false -Dcom. ...
- mysql基础知识详解
分享一些mysql数据库的基础知识. 1.每个客户端连接都会从服务器进程中分到一个属于它的线程.而该连接的相应查询都都会通过该线程处理.2.服务器会缓存线程.因此并不会为每个新连接创建或者销毁线程.3 ...
- AESDK AE中层类型的3种取得方式
有一部分属于类型标志,比如调节层,空对象层.用mSuites->LayerSuite7()->AEGP_GetLayerFlags去取 而灯光,文字这些信息,直接取类型即可 mSuites ...