线程池之介绍以及创建

一切开始:接口Exector

线程池的开始都是从这个Exector接口开始,后续又经由ExectorService、AbstractExecutorService、ThreadPoolExecutor等一系列的接口和方法来进一步丰富线程池的诸多功能,参考下面的图片(不是所有方法都列上了)。
截取的我想要的部分,可能不全面

线程池的开始:ThreadPoolExecutor

从上面的图片中可以看到ThreadPoolExecutor这个类,这才是我们在手动创建时使用的类,ThreadPoolExecutor类有许多关键的属性,具体的要看下源码里面的说明,如:

private static final int COUNT_BITS = Integer.SIZE - 3;
private static final int CAPACITY   = (1 << COUNT_BITS) - 1;
// runState is stored in the high-order bits  ==>>> 线程状态的标志值
private static final int RUNNING    = -1 << COUNT_BITS;
private static final int SHUTDOWN   =  0 << COUNT_BITS;
private static final int STOP       =  1 << COUNT_BITS;
private static final int TIDYING    =  2 << COUNT_BITS;
private static final int TERMINATED =  3 << COUNT_BITS;

然后在初始化线程池的时候使用的是ThreadPoolExecutor()方法。

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler)

corePoolSize:线程池的基本大小
即在没有任务需要执行的时候线程池的大小,并且只有在工作队列满了的情况下才会创建超出这个数量的线程。

maximumPoolSize:线程池中允许的最大线程数
线程池中的当前线程数目不会超过该值。如果队列中任务已满,并且当前线程个数小于maximumPoolSize,那么会创建新的线程来执行任务
注:线程池创建之后,可以调用setMaximumPoolSize()改变运行的最大线程的数目。

keepAliveTime:源码注释是:
when the number of threads is greater than the core, this is the maximum time that excess idle threads will wait for new tasks before terminating.
当线程值大于corePoolSize的值(即当前线程池里面的线程数量还不到corePoolSize的值
),那么多出来的线程的等待新任务的最长时间

TimeUnit:是等待时间的单位(枚举类型)
BlockingQueue:这个是用于在一些还未被执行的任务所放的队列,阻塞式的
ThreadFactory:创建线程的工厂,线程池为什么叫池的原因吧(个人觉得)
RejectedExecutionHandler:由于达到线程边界和队列容量而阻止执行时要使用的处理程序

上面的列出的是最完整的一个构造线程池的一个方法,ThreadPoolExecutor类也提供了其他各钟类型的构造方法(就是参数个数不同,有些参数是默认提供的不需要我们手动去赋值)。

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue) // 最简单的一个
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory)
 public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          RejectedExecutionHandler handler)
 public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler) // 最复杂的一个

更加简单方便的:Executors

从上面的提供的构造方法可以看到创建一个线程池最少也要5各参数,太麻烦了。其实还有更方便的方法,利用Executors类,其实是对ThreadPoolExecutor类一些方法的进一步封装。
Executors创建的线程池就包含经常说到的常用的四种线程池

下面介绍下这四种线程池:
1.Executors.newSingleThreadExecutor()

public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}

从源码可以看到其中corePoolSize=maximumPoolSize=1,而keepAliveTime = 0,存放任务使用的是LinkedBlockingQueue,这样该线程池中只有一个线程,任务都是一个一个执行的。
其中关于线程工厂和任务策略都是利用默认提供的,在源码中够可以找到:

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

2.Executors.newCachedThreadPool()
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue());

这个比较有意思的是corePoolSize = 0,而maximumPoolSize=Integer.MAX_VALUE,keepAliveTime=60,SynchronousQueue也是一种队列,这样线程池中线程个数就理论上为Integer.MAX_VALUE,但当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程。线程工厂和任务策略都是利用默认提供的跟newSingleThreadExecutor的一样。

3.Executors.newScheduledThreadPool(int corePoolSize)

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
    return new ScheduledThreadPoolExecutor(corePoolSize);
}

public ScheduledThreadPoolExecutor(int corePoolSize) {
    super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
          new DelayedWorkQueue());
}
//最后都是下面的方法
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue) {
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
         Executors.defaultThreadFactory(), defaultHandler);
}

corePoolSize = 手动赋值,而maximumPoolSize=Integer.MAX_VALUE,keepAliveTime=0,队列使用的是:DelayedWorkQueue
创建一个定长线程池,支持定时及周期性任务执行。延迟执行示例代码如下:

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

4.Executors.newFixedThreadPool(int nThreads)

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}
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=0,队列使用的是:LinkedBlockingQueue
创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值