从头认识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)-线程池的使用
在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, 这样频繁创建线程就会大大降低系 ...
随机推荐
- OFBiz:初始RequestHandler
RequestHandler,可以称之为请求处理器,在ControlServlet.init()中初始化: public class ControlServlet extends HttpServle ...
- 基于Python Tornado的在线问答系统
概述 本项目使用最新的Tornado开发.实现了在线提问,回答,评论等功能.使用到Tornado的generator,长轮询等等技术, 支持MySQL的异步连接. 详细 代码下载:http://www ...
- http请求返回405
普通情况下,是你用了默认method=get,须要改为post
- Ubuntu 12.04 安装 vsftpd
本篇文章由:http://xinpure.com/ubuntu-12-04-install-vsftpd/ 安装背景 wordpress 在线升级需要配置 ftp 帐号,之前用的是虚拟主机,都是带有 ...
- javascript获取地址栏参数
http://gzycm520.blog.51cto.com/175220/71030方法一: <script type="text/javascript"> < ...
- Linux命令-目录处理命令:mv
注意:在linux下面,剪切文件和改名是同一个命令mv,而不是两个独立的命令. mv /tmp/beijing/chaoyangqu /root 移动chaoyangqu目录到root目录下面 mv ...
- WCF学习之三, 寄宿方式 代码,配置文件
可以通过代码或者配置文件寄宿WCF服务,在使用过程中的一些心得,记录一下,方便后续查阅. 预备知识,几个地址的作用 1. behavior.HttpGetUrl 定义元数据的地址,如果不定义基地址, ...
- 求子数组的最大和要求O(n)
//求子数组的最大和 //输入一个整形数组.有整数也有负数,数组中连续一个或多个子数组,每一个子数组都有一个和,求全部子数组的和的最大值,要求时间复杂度O(n) #include<iostrea ...
- Django URL中r的意思
例如: urlpatterns = patterns('', # ... (r'^time/plus/\d+/$', hours_ahead), # ... ) 正则表达式字符串的开头字母“r”. 它 ...
- Go语言核心之美 4.3-多返回值
在Go语言中.函数能够有多个返回值,这个特性我们已经在之前的样例见过非常多,非常多标准库函数都会返回两个值,一个是期望得到的函数执行结果,另外一个是函数出错时的错误值. 以下的程序是findlinks ...