在Java开发过程中经常需要用到线程,为了减少资源的开销,提高系统性能,Java提供了线程池,即事先创建好线程,如果需要使用从池中取即可,Java中创建线程池有以下的方式,

1、使用ThreadPoolExecutor类

2、使用Executors类

其实这两种方式在本质上是一种方式,都是通过ThreadPoolExecutor类的方式,下面分析其使用方式。

一、ThreadPoolExecutor的方式

1、使用方法

查看JDK的源码,ThreadPoolExecutor类提供了以下构造方法,

可以看到有四个构造方法,先看第一个构造方法,其代码如下,

public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}

从上面的代码中可以确定,我们需要传的参数有corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue

下面对这几个参数进行说明

corePoolSize:线程池的核心线程数;

maximumPoolSize:线程池的最大线程数;

keepAliveTime:线程池空闲时线程的存活时长;

unit:线程存活时长大单位,结合上个参数使用;

workQueue:存放任务的队列,使用的是阻塞队列;

在这个方法中调用了另外的一个构造方法,即上图中四个构造方法中的第四个,从源码中得知,一个线程池包含的属性共有corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory、handler七个,上面说到了五个,下面是其他两个的含义,

threadFactory:线程池创建线程的工厂;

handler:在队列(workQueue)和线程池达到最大线程数(maximumPoolSize)均满时仍有任务的情况下的处理方式;

上面的七个参数,也即ThreadPoolExecutor的第四个构造方法需要的参数。

我们再来看中间的两个构造方法,和第一个的区别在于,第二个和第三个指定了创建线程的工厂和线程池满时的处理策略。

通过上面的方式便创建了线程池

二、Executors的方式

1、使用方法

Executors类提供了下面的构造方法,

可以看到提供了约10个的构造方法,但是发现其方法返回值为ExecutorService,这不是我们要的ThreadPoolExecutor那,别急,看下ExecutorService这个类是什么,

其源码如下,

其是一个接口,和ThreadPoolExecutor没什么关系那,不对,可以大胆猜想下,ThreaPoolExecutor可以实现接口,验证下我们的猜想,

ThreadPoolExecutor继承了AbstractExecutorService

AbstractExecutorService抽象类实现了ExecutorService接口,那么ThreadPoolExcutor和ExecutorService就有了关系。

我们再挑选ExecutorService中的方法看下其具体实现,

public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}

从上面的代码中可以看出,其返回的是ThreaPoolExecutor对象,调用的是ThreaPoolExecutor类四个构造方法中的第一个。

总结,上面两种创建线程池的方式,其本质都是通过ThreaPoolExecutor类的构造方法的方式,所以ThreaPoolExecutor是重点。

最新文章

  1. topcoder SRM 628 DIV2 BracketExpressions
  2. 图片加载框架Picasso解析
  3. Android线程管理(三)&mdash;&mdash;Thread类的内部原理、休眠及唤醒
  4. 图文详解如何搭建Windows的Android C++开发环境
  5. UI事件之unload、resize和scroll
  6. javascript 变量转义
  7. mariadb 设置远程访问
  8. Java-List泛型的用处(能够使用传入泛型对象的方法)
  9. java并发之线程执行器(Executor)
  10. Spring源码分析:Spring IOC容器初始化
  11. 04 SimpleAdapter
  12. 安卓开发学习笔记(四):Android Stuidio无法实现隐式Intent是为什么?
  13. c#实现识别图片上的验证码数字
  14. bash array
  15. 主机连接虚拟机的mysql 记录
  16. 【译】第19节---数据注解-NotMapped
  17. ES6 阮一峰阅读学习
  18. SS iproute2,nslookup,dig
  19. 开机自启:bat实现一次性打开win7中的常用软件和文件夹
  20. ltp-ddt eth过程中遇到的问题

热门文章

  1. queryRuner如何获得bean对象,当这个bean对象中包含其他对象的时候
  2. Python解决中文字符的问题
  3. HIVE SQL JOIN
  4. bzoj 4199: [Noi2015]品酒大会 后缀树
  5. codevs1060 搞笑世界杯
  6. 配置 VS Code 调试 PHP
  7. 使用IronPython集成Python和.NET
  8. 白话算法(6) 散列表(Hash Table)从理论到实用(中)
  9. 洛谷【P1601】A+B Problem(高精)
  10. java多线程编程核心技术——第四章总结