ExecutorService 的理解和使用
前言:
我们之前使用线程的时候都是使用new Thread来进行线程的创建,但是这样会有一些问题。如:
a. 每次new Thread新建对象性能差。
b. 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致死机或oom。
c. 缺乏更多功能,如定时执行、定期执行、线程中断。
相比new Thread,Java提供的四种线程池的好处在于:
a. 重用存在的线程,减少对象创建、消亡的开销,性能佳。
b. 可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。
c. 提供定时执行、定期执行、单线程、并发数控制等功能。
而我们今天来学习和掌握另外一个新的技能,特别像一个线程池的一个接口类ExecutorService,下面我们来了解下java中Executors的线程池
Java通过Executors提供四种线程池,分别为:
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
(1). newCachedThreadPool
创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。示例代码如下:

ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
final int index = i;
try {
Thread.sleep(index * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
} cachedThreadPool.execute(new Runnable() { @Override
public void run() {
System.out.println(index);
}
});
}

线程池为无限大,当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程。
(2). newFixedThreadPool
创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。示例代码如下:

ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
for (int i = 0; i < 10; i++) {
final int index = i;
fixedThreadPool.execute(new Runnable() { @Override
public void run() {
try {
System.out.println(index);
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}

因为线程池大小为3,每个任务输出index后sleep 2秒,所以每两秒打印3个数字。
定长线程池的大小最好根据系统资源进行设置。如Runtime.getRuntime().availableProcessors()。可参考PreloadDataCache。
(3) newScheduledThreadPool
创建一个定长线程池,支持定时及周期性任务执行。延迟执行示例代码如下:

ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
scheduledThreadPool.schedule(new Runnable() { @Override
public void run() {
System.out.println("delay 3 seconds");
}
}, 3, TimeUnit.SECONDS);

表示延迟3秒执行。
定期执行示例代码如下:

scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("delay 1 seconds, and excute every 3 seconds");
}
}, 1, 3, TimeUnit.SECONDS);

表示延迟1秒后每3秒执行一次。
ScheduledExecutorService比Timer更安全,功能更强大,后面会有一篇单独进行对比。
(4)、newSingleThreadExecutor
创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。示例代码如下:

ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
final int index = i;
singleThreadExecutor.execute(new Runnable() { @Override
public void run() {
try {
System.out.println(index);
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
博客来源:https://www.cnblogs.com/zhaoyan001/p/7049627.html
ExecutorService 的理解和使用的更多相关文章
- ExecutorService 的理解与使用
ExecutorService 的理解与使用 http://my.oschina.net/bairrfhoinn/blog/177639 Java线程池ExecutorService http:// ...
- Java并发编程 - Executor,Executors,ExecutorService, CompletionServie,Future,Callable
一.Exectuor框架简介 Java从1.5版本开始,为简化多线程并发编程,引入全新的并发编程包:java.util.concurrent及其并发编程框架(Executor框架). Executor ...
- Android Tips – 填坑手册
出于: androidChina http://www.androidchina.net/3595.html 学习 Android 至今,大大小小的坑没少踩,庆幸的是,在强大的搜索引擎与无私奉献的 ...
- 收藏的技术文章链接(ubuntu,python,android等)
我的收藏 他山之石,可以攻玉 转载请注明出处:https://ahangchen.gitbooks.io/windy-afternoon/content/ 开发过程中收藏在Chrome书签栏里的技术文 ...
- android 开发从入门到精通
Android-Tips This is an awesome list of tips for android. If you are a beginner, this list will be t ...
- Java处理Exception无法捕获的异常
场景: 使用try...catch(Exception e){}来捕获异常,执行过程中线程中断或阻塞了,但是catch块中却并没有捕获到异常信息. try{ // 此处可能是调用一个远程的接口,或是调 ...
- Java高并发编程(四)
一.Executor执行器 1.Executor接口,java线程池框架中的顶层接口,提供一个execute方法来执行任务 import java.util.concurrent.Executor; ...
- ot
https://blog.csdn.net/notice520/article/details/8135600 | android中的跨进程通信的实现(一)——远程调用过程和aidl - CSDN博客 ...
- java 与大数据学习较好的网站
C# C#中 Thread,Task,Async/Await,IAsyncResult 的那些事儿!https://www.cnblogs.com/doforfuture/p/6293926.html ...
随机推荐
- python 3.5学习笔记(第四章)
本章内容: 一..装饰器 二.生成器 三.迭代器 四.python中的内置方法 五.json & pickle 的数据序列化及反序列化 六.程序目录结构规范 七.补充内容 一.装饰器: 1.概 ...
- linux + .Net Core + Docker 注意事项
开发环境为windows下 1.静态文件 需设置成始终拷贝: 2.文件路径不要用\\来拼接,使用文件库处理: Path.Combine(Directory.GetCurrentDirectory(), ...
- 编码原理_base64编码原理
1.1 Base64编码原理 1.1.1 概要: Base64是通讯传输中较为常见的编码方式之一. (注意是编码算法,而非加密算法) 参数传输的过程中会经常遇到的一种情况:使用英文不会涉及到乱码, ...
- ForkJoinPool分支/合并框架工程使用的工作窃取
ForkJoinPool分支/合并框架 在必要的情况下,讲一个大任务,进行拆分(fork)成若干个小任务(拆到不可拆为止),再将一个个小的任务运算的结果进行join汇总. 工作窃取的背景 分支/合并框 ...
- Android studio 混淆打包安装后报错NullPointerException int java.util.List.size()
菜鸟的我,尝试混淆打包app...打包之前没有什么问题,混淆打包之后遇到各种问题.首先,感谢原博主的分享.解决了我的问题.谢谢. 原文地址:http://blog.csdn.net/tou_star/ ...
- ThinkPHP 添加数据到数据库失败
ThinkPHP 添加数据到数据库失败 一般情况下会先检查一下几个方面 检查控制器或Model名是否有误 检查需要插入的数据是否为空或者缺失参数 检查数据表名及字段名称(大部分下都是字段名有误出错的) ...
- vmware虚拟机三种网卡
vmware虚拟机三种网卡 vmware为我们提供了三种网络工作模式,它们分别是:Bridged(桥接模式).NAT(网络地址转换模式).Host-Only(仅主机模式). 打开vmware虚拟机 ...
- python UUID
UUID介绍 UUID是128位的全局唯一标识符,通常由32字节的字符串表示.它可以保证时间和空间的唯一性,也称为GUID,全称为:UUID ―― Universally Unique IDentif ...
- Android开发进阶——自定义View的使用及其原理探索
在Android开发中,系统提供给我们的UI控件是有限的,当我们需要使用一些特殊的控件的时候,只靠系统提供的控件,可能无法达到我们想要的效果,这时,就需要我们自定义一些控件,来完成我们想要的效果了.下 ...
- Loadrunner参数(摘)
一.占有率分析 1. 平均事务响应时间 Average Transaction Response Time 优秀:<2s 良好:2-5s 及格:6-10s 不及格:>10s 2. 每秒点击 ...