博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java多线程之使用执行器(Executors)(Thinking in Java)
阅读量:2350 次
发布时间:2019-05-10

本文共 3688 字,大约阅读时间需要 12 分钟。

JavaSE5的java.util.concurrent包中的执行器(Executor)将为你管理Thread对象,从而简化了并发编程。Executor在客户端和任务执行之间提供了一个间接层;与客户端直接执行任务不同,这个中介对象将执行任务。Executor允许你管理异步任务的执行,而无须显式地管理线程的生命周期。Executor在JavaSe5/6中是启动任务的优选方法。

如果程序中创建了大量的生命周期很短的线程,应该使用线程池。一个线程池中包含许多准备运行的空闲线程。将Runnable对象交给线程池,就会有一个线程调用run()方法。当run()方法退出时,线程不会死亡,而是在池中准备为下一个请求提供服务。

另一个使用线程池的理由是减少并发线程的数目。创建大量线程会大大降低性能甚至使虚拟机崩溃。如果有一个会创建许多多线程的算法,应该使用一个线程数“固定的”线程池以限制并发线程的总数。

执行器(Executors)类有许多静态工厂方法用来构建线程池,下面的表对这些方法进行了汇总:

方法 描述
newFixedThreadPool 该池包含固定数量的线程,空闲线程会被一直保留
newCachedThreadPool 必要时创建新线程,空闲线程会被保留60秒
newSingleThreadPool 只有一个线程的线程池,该线程顺序执行每一个提交的任务(类似于Swing事件分配线程)
newScheduledThreadPool 用于预定执行而构建的固定线程池,替代java.util.Timer
newSingleThreadScheduledPool 用于预定执行而构建的单线程池

我们可以使用Executor来代替在MoreBasicThreads.java中显示地创建Thread对象,LiftOff对象知道如何运行具体的任务,与命令设计模式一样,它暴露了要执行的单一方法。ExecutorService(具有服务生命周期的Executor,例如关闭)知道如何构建恰当的上下文来执行Runnable对象。在下面的示例中,CachedThreadPool将为每个任务都创建一个线程。注意,ExecutorService对象是使用静态的Executor方法创建的,这个方法可以确定其Executor类型。

测试CachedThreadPool:

package chapter21;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/** * 测试CachedThreadPool  */public class CachedThreadPool {	public static void main(String[] args) {		//根据需要创建线程		ExecutorService exec = Executors.newCachedThreadPool();		for(int i =0; i < 5; i ++) {
//LiftOff参见前一篇博客  exec.execute(new LiftOff());//将任务放入线程池中执行}//当所有线程执行完成后,关闭线程池exec.shutdown();}} 运行结果: #0(9), #3(9), #2(9), #1(9), #4(9), #3(8), #0(8), #4(8), #3(7), #0(7), #4(7), #1(8), #2(8), #1(7), #2(7), #1(6), #2(6), #3(6), #1(5), #0(6), #2(5), #0(5), #3(5), #4(6), #2(4), #1(4), #0(4), #2(3), #3(4), #0(3), #3(3), #0(2), #3(2), #0(1), #3(1), #0(LiftOff!), #3(LiftOff!), #1(3), #4(5), #2(2), #1(2), #1(1), #4(4), #2(1), #1(LiftOff!), #4(3), #4(2), #4(1), #2(LiftOff!), #4(LiftOff!),  测试FixedThreadPool: package chapter21;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/** * 测试FixedThreadPool */public class FixedThreadPoolTest {	public static void main(String[] args) {		//创建一个有5个线程的线程池		ExecutorService exec = Executors.newFixedThreadPool(5);		for(int i = 0; i < 5; i ++) {			exec.execute(new LiftOff());		}		//当所有的任务执行完毕后,关闭线程池		exec.shutdown();	}} 执行结果: #0(9), #0(8), #0(7), #0(6), #0(5), #0(4), #0(3), #0(2), #0(1), #0(LiftOff!), #1(9), #1(8), #1(7), #1(6), #1(5), #1(4), #1(3), #1(2), #1(1), #1(LiftOff!), #2(9), #2(8), #2(7), #2(6), #2(5), #2(4), #2(3), #2(2), #2(1), #2(LiftOff!), #3(9), #3(8), #3(7), #3(6), #3(5), #3(4), #3(3), #3(2), #3(1), #3(LiftOff!), #4(9), #4(8), #4(7), #4(6), #4(5), #4(4), #4(3), #4(2), #4(1), #4(LiftOff!),  SingleThreadExecutor就像是线程数量为1的FixedThreadPool。这对于你希望在另一个线程里持续运行的任何事物(长期存活的任务)来说,都是很有用的,例如监听进入的套接字连接的任务,它对于希望在线程中运行的短任务也同样很方便,例如,更新本地或远程日志的小任务或者事件分发线程。 如果向SingleThreadExecutor提交了多个任务,那么这些任务将排队,每个任务都会在下一个任务开始之前运行结束,所有的任务将使用相同的线程。在下面的示例中,你可以看到每个任务都是按照它们被提交的顺序,并且是在下一个任务开始之前完成的。因此,SingleThreadExecutor会序列化所有交给它的任务,并会维护它自己(隐藏)的悬挂任务队列。 下面演示SingleThreadPool: package chapter21;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/** * 测试SingleThreadExecutor */public class SingleThreadExecutorTest {	public static void main(String[] args) {		ExecutorService exec = Executors.newSingleThreadExecutor();		for(int i = 0; i < 5; i ++) {			exec.execute(new LiftOff());		}		//当所有任务执行完毕后,关闭线程池		exec.shutdown();	}} 运行结果: #0(9), #0(8), #0(7), #0(6), #0(5), #0(4), #0(3), #0(2), #0(1), #0(LiftOff!), #1(9), #1(8), #1(7), #1(6), #1(5), #1(4), #1(3), #1(2), #1(1), #1(LiftOff!), #2(9), #2(8), #2(7), #2(6), #2(5), #2(4), #2(3), #2(2), #2(1), #2(LiftOff!), #3(9), #3(8), #3(7), #3(6), #3(5), #3(4), #3(3), #3(2), #3(1), #3(LiftOff!), #4(9), #4(8), #4(7), #4(6), #4(5), #4(4), #4(3), #4(2), #4(1), #4(LiftOff!), 

转载地址:http://fklvb.baihongyu.com/

你可能感兴趣的文章
ZooKeeper 配置
查看>>
11.组合模式--Composite
查看>>
12.轻量模式--Flyweight
查看>>
13.外观模式--Facade
查看>>
开源史上最成功的八个开源软件
查看>>
More Effective C++读书笔记
查看>>
关于assert,ASSERT,TRACE和VERIFY
查看>>
关于C++中野指针的说明
查看>>
Linux/Unix环境下的make和makefile详解
查看>>
SourceInsight添加对汇编语言文件.s和.S的支持
查看>>
windows 下实现函数打桩:拦截API方式
查看>>
获取Windows系统版本
查看>>
漫谈兼容内核之十二:Windows的APC机制
查看>>
21.windbg-.lastevent、!analyze(dump分析、异常错误码查询)
查看>>
16.windbg-.frame、dt(切换局部上下文、查找结构体)
查看>>
开源任务管理器 Process Hacker (Windows)
查看>>
快速发现Windows中毒的工具:Process Hacker
查看>>
Process Hacker源码中的用户态hook的做法
查看>>
Get IT技能知识库 50个领域一键直达
查看>>
浅析C++中的this指针及汇编实现
查看>>