在许多应用中需要频繁的创建许多生命周期很短的线程,如果用传统方法的话就会造成大量的资源了浪费,java的设计者们考虑到了这点在java中加入了线程池这个特性,它负责管理大量的线程的创建销毁等操作。

  首先我们需要了解一个类:java.util.concurrent.Executors(执行器)

  执行器类拥有大量的静态工厂方法用于创建线程池

  

方法 描述
newCachedThreadPool 必要时创建线程,处于空闲状态的线程将被保留60秒
newFixedThreadPool 拥有固定数量的线程,并且不会自动销毁空闲状态的线程
newSingleThreadExecutor 该线程池仅有一个线程,会顺序执行任务队列
newScheduledThreadPool 用于预约执行任务的固定线程池
newSingleThreadScheduledExecutor  用于预约执行任务的单线程池

 

 下面我们来详细了解下这些线程池。

  newCachedThreadPool:通过名称,不难看出这个方法创建出的线程池,具有数量可变,并且在需要的时候会自动创建更多的线程,并且会自动销毁线程。

  newFixedThreadPool:此线程池与newCachedThreadPool构建出的线程池的主要区别是,线程池在数量上固定,如果任务数量达到上限的话,就会将多余任务加入任务队列,等线程池空出线程时即可执行,这种线程池并不会销毁空闲线程。

  newSingleThreadExecutor:此方法创建出的线程池相较于其他两个线程较为特殊,此方法创建出的线程数量仅仅为1,也就是说所有除了正在执行的任务外,其余任务均在任务队列中,当线程中的任务执行完毕后,任务队列的第一个任务进入线程开始执行。

  newScheduledThreadPool与 newSingleThreadScheduledExecutor:这两个方法创建出的线程池是用于预定执行的线程池,他们可以用于在初始化后延迟执行,或周期性的执行,两种线程池大体相同,唯一的区别就是可同时执行的线程数量。

  当你挑选完的线程池后就需要创建以及使用线程池:

    大概步骤为以下3步:

    (1)调用执行器类(Executors)的静态方法来创建线程池

    (2)调用线程池的submit方法提交Runnable或Callable对象

    (3)当不需要添加更多的任务时,调用shutdown关闭入口

  下面通过代码来逐步操作:

    

 //创建线程池对象
ExecutorService service = Executors.newCachedThreadPool();
//创建一个用于递增输出i值的runnable对象
Runnable runnable = new Runnable() {
@Override
public void run() {
for (int i = 0; i < 400; i++) {
System.out.println(i);
}
}
};
//调用线程池的submit方法传入runnable(传入的runnable将会自动执行)
service.submit(runnable);
service.submit(runnable);
//当不需要传入更多的任务时调用shutdown方法来关闭入口
service.shutdown();

 

 需要注意的是如果希望直接停止线程池的一切任务是无法通过shutdown来操作的,因为shutdown仅仅是关闭了入口,但是已经加入的任务还是会继续执行的,这时我们可以调用线程池的shutdownNow方法来操作,shutdownNow的作用是用来关闭线程池的入口并且会尝试终止所有当前线程池内的任务。

//用来关闭线程池入口以及终止所有正在执行的任务
service.shutdownNow();

  service的submit方法会返回一个Future<?>类型的对象,然而这是一个怎样的类型呢?让我们来看一下api中的方法摘要:

  

  从方法摘要中可以看出该对象用于在加入线程池以后能够对此任务进行取消,查看状态等操作,如果说在加入线程池以后有可能会取消此任务的话就需要,在submit的时候就需要保存好Future对象。

         //保存Future<?>
Future<?> run2 = service.submit(runnable); //用于查看是否已经执行完毕,返回类型为boolean
System.out.println(run2.isDone()); //取消任务,如果需要中断的话参数为true
run2.cancel(true);

  关于线程池的简单操作大概就有这些,关于线程池的更多信息还需要深入的研究,java的最大优点是开源,也就是说想要深入学习其原理最好的方法也就是查看源码,我也会在后面补充上线程池的源码分析,希望大家支持:-D。

线程池 (thread pool) 的类型与实现方式的更多相关文章

  1. C#多线程实现方法——线程池(Thread Pool)

    ThreadPool使用 同步机制   ThreadPool使用 需要定义waitcallback委托形式如 public delegate void WaitCallback(object stat ...

  2. 简易线程池Thread Pool

    1. 基本思路 写了个简易的线程池,基本的思路是: 有1个调度线程,负责维护WorkItem队列.管理线程(是否要增加工作线程).调度(把工作项赋给工作线程)等 线程数量随WorkItem的量动态调整 ...

  3. MySQL线程池(THREAD POOL)的原理

    MySQL常用(目前线上使用)的线程调度方式是one-thread-per-connection(每连接一个线程),server为每一个连接创建一个线程来服务,连接断开后,这个线程进入thread_c ...

  4. 使用boost实现线程池thread pool | boost thread pool example

    本文首发于个人博客https://kezunlin.me/post/f241bd30/,欢迎阅读! boost thread pool example Guide boost thread pool ...

  5. MySQL--线程池(Thread Pool)

    ================================================================= 线程池技术 在MySQL社区版中,MySQL使用one-thread ...

  6. javade多任务处理之Executors框架(线程池)实现的内置几种方式与两种基本自定义方式

    一 Executors框架(线程池) 主要是解决开发人员进行线程的有效控制,原理可以看jdk源码,主要是由java.uitl.concurrent.ThreadPoolExecutor类实现的,这里只 ...

  7. Spring中的定时调度(Scheduling)和线程池(Thread Pooling)

    使用triggers和SchedulerFactoryBean来包装任务 我们已经创建了job details,jobs.我们同时回顾了允许你调用特定对象上某一个方法的便捷的bean. 当然我们仍需要 ...

  8. 基于C++11的线程池,简洁且可以带任意多的参数

    咳咳.C++11 加入了线程库,从此告别了标准库不支持并发的历史.然而 c++ 对于多线程的支持还是比较低级,稍微高级一点的用法都需要自己去实现,譬如线程池.信号量等.线程池(thread pool) ...

  9. 如何决定Web应用的线程池大小

    线程池(Thread Pool)在Web应用中线程池的大小决定了在任何一个时间点应用可以处理请求的并发数.如果一个系统收到的请求数超过了线程池的大小,那么超出的请求要么进入等待队列要么被拒绝.请注意, ...

随机推荐

  1. metal的gpu query

    https://developer.apple.com/documentation/metal/mtlcommandbuffer/1639924-gpustarttime gpuStartTime 看 ...

  2. trilinear filter

    之前对三线型过滤理解有些问题更新一下 三线性采样点 一次sample采样点是8 (u,v,d) d是个分数 作为权重 miplevel floor(d)向上取整 在这级mipmap上用uv 采样4个点 ...

  3. linux ubuntu下abaqus-6.14安装破解完全指南

    本人亲测可用 目录 安装前准备 安装过程 机器配置 腾讯云服务器 ubuntu server 16.10 1.首先要在服务器上安装gui及相关依赖 sudo apt-get install ubunt ...

  4. (转)Vue2.0 推荐环境

    Vue2.0 新手完全填坑攻略——从环境搭建到发布 http://www.jianshu.com/p/5ba253651c3b Jinkey原创感谢 showonne.yubang 技术指导Demo ...

  5. C# this.Hide()

    C# this.Hide() 第一次用的时候是在_Load函数里: BookSystem bs = new BookSystem();             bs.ShowDialog();     ...

  6. EventBus的粘性事件

    下午赶去公司解决了电台业务首次语音搜台后(用到服务,但只出一个独立的Activity,主界面并没有打开)不能听歌识曲的问题. 排查到最后,去识别的消息确实是发出去了,但是却没有收到,没有收到消息当然不 ...

  7. 对象的序列化(Serialization)

    一.什么是序列化 序列化表示将一个对象转换成可存储或可传输的状态,序列化后对象可以在网络上进行传输,也可以存储到本地.对象的寿命通常随着生成该对象的程序的终止而终止.有时候,可能需要将对象的状态保存下 ...

  8. ES6 数组扩展

    1....扩展运算符 该运算符将一个数组,变为参数序列. 作用:(1)代替aplly 'use strict'; Math.max(...[2,5,8]) (2)将字符串转为数组 2.Array.fr ...

  9. Mysql报错......\xE6\x80\xBB\xE7\x9B\x91' for column...

    Mysql添加表中字符报错:Incorrect string value: '\xE6\x80\xBB\xE7\x9B\x91' for column 'postName' at row 1 原因:字 ...

  10. 域对象的引用,ActionContext 和ServletActionContext类的使用

    ActionContext 获取 域引用的map ServletActionContext获取具体域对象 //域范围 ActionContext ac = ActionContext.getConte ...