在许多应用中需要频繁的创建许多生命周期很短的线程,如果用传统方法的话就会造成大量的资源了浪费,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. .Net Core+Angular Cli/Angular4开发环境搭建教程

    一.基础环境配置1.安装VS2017v15.3或以上版本2.安装VSCode最新版本3.安装Node.jsv6.9以上版本4.重置全局npm源,修正为淘宝的NPM镜像:npminstall-gcnpm ...

  2. Linux C高级编程——文件操作之系统调用

    Linux C高级编程文件操作之系统调用 宗旨:技术的学习是有限的,分享的精神是无限的.           库函数是一些完毕特定功能的函数.一般由某个标准组织制作公布,并形成一定的标准.使用库函数编 ...

  3. tee -a /var/log/jd.log

    原文: http://man.linuxde.net/tee --------------------------------------------------------------------- ...

  4. select()/poll() 的内核实现

    mark 引用:http://janfan.cn/chinese/2015/01/05/select-poll-impl-inside-the-kernel.html 文章 select()/poll ...

  5. 2017.12.12 架构探险-第一章-从一个简单的web应用开始

    参考来自:<架构探险>黄勇 著 1 使用IDEA搭建MAVEN项目 1.1 搭建java项目 (1)创建java项目 为了整个书籍的项目,我创建了一个工程,在这个工程里创建了每个章节的mo ...

  6. Python cx_Oracle问题处理

    今天第一次使用Python连接Oracle数据库(多么可怕,三年码农没用Python手动连过Oracle) 首先: pip install cx_Oracle 好,安装完成,测试代码如下: from ...

  7. Linux中查看jdk安装目录、Linux卸载jdk、rpm命令、rm命令参数

    一.查看jdk安装目录 [root@node001 ~]# whereis java java: /usr/bin/java /usr/local/java #java执行路径 [root@node0 ...

  8. chromedriver中的浏览器选项

    There are lots of command lines which can be used with the Google Chrome browser. Some change behavi ...

  9. CentOS 6.4 编译安装 gcc 4.8.1(转)

    今天在isocpp上看到“GCC 4.8.1 released, C++11 feature complete”这个消息,非常兴奋.终于有一个全面支持C++11语言特性的编译器了! 当然了,gcc仅仅 ...

  10. redis可视化工具的安装和调试

    Redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted set ...