ThreadPoolExecutor的源码解读

public class ThreadPoolExecutor extends AbstractExecutorService

    ThreadPoolExecutor 继承了ExecutorService接口的抽象实现类AbstractExecutorService,提供了四个构造方法供编码者使用:


前面三个方法都是给定默认参数替代没有传递的参数然后this调用最后一个满参数的构造函数,源代码如下:

[java]  view plain  copy
  1. public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {  
  2.         this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler);  
  3.     }  

上面这个构造方法就提供了一个默认的线程工厂和一个默认的拒绝handler。

通过ThreadPoolExecutor的构造方法得到的线程池使用方法和Executors.newFixedThreadPool()方法得到的线程池使用方式是一样的,你可以以ExecutorService来接收它,通过ExecutorService的sumbit()方法提交你要管理的线程。

这里再解读一下线程工厂和拒绝handler的源码,首先从handler开始:

    这里的RejectedExecutionHandler是java的concurrent包下的一个接口,java对其提供了四种实现:

    它的主要负责的是在线程池内的线程都处于工作状态时,有新的任务提交进来的处理工作。

        

    1.AbortPolicy  从名字上面就可以看到,Abort-舍弃、终止,直接设置提交进来的任务,但是它在舍弃前还抛出一个异常,这也是未提交策略参数时,使用的默认策略:

[java]  view plain  copy
  1. public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {  
  2.             throw new RejectedExecutionException();  
  3.         }  
[java]  view plain  copy
  1. /** 
  2.      * The default rejected execution handler 
  3.      */  
  4.     private static final RejectedExecutionHandler defaultHandler = new AbortPolicy();  

    2.CallerRunsPolicy 这个策略是在线程池满负荷时,将会一直重试将此线程任务添加到线程池中。注意,如果线程池采用此种策略,可能会导致占用cpu的过多的时间进行重新添加操作,导致真正在线程池中需要执行的线程分不到cpu的时间片。

[java]  view plain  copy
  1. /** 
  2.          * Executes task r in the caller's thread, unless the executor 
  3.          * has been shut down, in which case the task is discarded. 
  4.          * @param r the runnable task requested to be executed 
  5.          * @param e the executor attempting to execute this task 
  6.          */  
  7.         public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {  
  8.             if (!e.isShutdown()) {  
  9.                 r.run();  
  10.             }  
  11.         }  

    3.DiscardPolicy  这个策略直接贴源码吧

[java]  view plain  copy
  1. /** 
  2.          * Does nothing, which has the effect of discarding task r. 
  3.          * @param r the runnable task requested to be executed 
  4.          * @param e the executor attempting to execute this task 
  5.          */  
  6.         public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {  
  7.         }  

看见了吗,注释里面大大的Does nothing。人家啥也不干,方法体内就是空的。你任务没了他都不给你提示。

    4.DiscardOldestPolicy  这个策略和上面的类似,不过它是将线程池队列最老一个任务枪毙,然后把这个任务拉进来

[java]  view plain  copy
  1. /** 
  2.          * Obtains and ignores the next task that the executor 
  3.          * would otherwise execute, if one is immediately available, 
  4.          * and then retries execution of task r, unless the executor 
  5.          * is shut down, in which case task r is instead discarded. 
  6.          * @param r the runnable task requested to be executed 
  7.          * @param e the executor attempting to execute this task 
  8.          */  
  9.         public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {  
  10.             if (!e.isShutdown()) {  
  11.                 e.getQueue().poll();  
  12.                 e.execute(r);  
  13.             }  
  14.         }  

以上为Handle java提供的实现类的解答,如果这四种不满足使用需求,希望处理方法更加复杂一点,比如将多出来的任务放到某个地方,等这边线程池过了高峰再去处理的话,可以自己实现RejectedExecutionHandler接口,在rejectedExecution()方法体中写入你需要的逻辑。


接下来看看线程工厂的源码:

    ThreadFactory也是concurrent包下的接口,贴下源码和注释:

[java]  view plain  copy
  1. /** 
  2.  * An object that creates new threads on demand.  Using thread factories 
  3.  * removes hardwiring of calls to {@link Thread#Thread(Runnable) new Thread}, 
  4.  * enabling applications to use special thread subclasses, priorities, etc. 
  5.  * 
  6.  * <p> 
  7.  * The simplest implementation of this interface is just: 
  8.  * <pre> 
  9.  * class SimpleThreadFactory implements ThreadFactory { 
  10.  *   public Thread newThread(Runnable r) { 
  11.  *     return new Thread(r); 
  12.  *   } 
  13.  * } 
  14.  * </pre> 
  15.  * 
  16.  * The {@link Executors#defaultThreadFactory} method provides a more 
  17.  * useful simple implementation, that sets the created thread context 
  18.  * to known values before returning it. 
  19.  * @since 1.5 
  20.  * @author Doug Lea 
  21.  */  
  22. public interface ThreadFactory {  
  23.   
  24.     /** 
  25.      * Constructs a new {@code Thread}.  Implementations may also initialize 
  26.      * priority, name, daemon status, {@code ThreadGroup}, etc. 
  27.      * 
  28.      * @param r a runnable to be executed by new thread instance 
  29.      * @return constructed thread, or {@code null} if the request to 
  30.      *         create a thread is rejected 
  31.      */  
  32.     Thread newThread(Runnable r);  
  33. }  

可以看到,接口内只有一个方法,newThread(),从名字和注释都可以知道,主要功能就是创建一个新的线程。

ThreadPoolExecutor中的默认线程工厂是类Executors的一个内部类

[java]  view plain  copy
  1. /** 
  2.      * The default thread factory 
  3.      */  
  4.     static class DefaultThreadFactory implements ThreadFactory {  
  5.         private static final AtomicInteger poolNumber = new AtomicInteger(1);  
  6.         private final ThreadGroup group;  
  7.         private final AtomicInteger threadNumber = new AtomicInteger(1);  
  8.         private final String namePrefix;  
  9.   
  10.         DefaultThreadFactory() {  
[java]  view plain  copy
  1. public final native void wait(long timeout) throws InterruptedException;  

SecurityManager s = System.getSecurityManager(); group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup(); namePrefix = "pool-" + poolNumber.getAndIncrement() + "-thread-"; } public Thread newThread(Runnable r) { Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0); if (t.isDaemon()) t.setDaemon(false); if (t.getPriority() != Thread.NORM_PRIORITY) t.setPriority(Thread.NORM_PRIORITY); return t; } }上面默认的线程工厂也就是在创建线程时,设置了线程的组,线程名和优先级。我们也可以自己去实现ThreadFactory类,创建线程。下次有机会补上代码及测试。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值