线程池汇总

一、线程池:

Executors是创建线程池的工厂方法,首先看Executors的所有方法:其中有三个比较常用:



 

以上三个方法返回的对象不同,其实看看源码就清楚了:

public interface ScheduledExecutorService extends ExecutorService {
   ScheduledFuture<?> schedule(Runnable arg0, long arg1, TimeUnit arg3);

   <V> ScheduledFuture<V> schedule(Callable<V> arg0, long arg1, TimeUnit arg3);

   ScheduledFuture<?> scheduleAtFixedRate(Runnable arg0, long arg1, long arg3, TimeUnit arg5);

   ScheduledFuture<?> scheduleWithFixedDelay(Runnable arg0, long arg1, long arg3, TimeUnit arg5);
}

 

一、线程池执行如下:有新任务——>在corePoolSize范围内新增线程处理任务——>corePoolSize满,则放入任务队列——>队列满,则在maximumPoolSize范围内新增线程处理任务——>队列满,报错抛异常

 

二、newFixedThreadPool(int arg)和newSingleThreadScheduledExecutor()线程池结构:

1)先看下newFixedThreadPool(int arg)固定线程数的线程池源码,证明corePoolSize和maximumPoolSize相等,因为任务队列是无界的,所以一般不会用到最大线程参数,跟corePoolSize数量一样即可。

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

 其中ThreadPoolExecutor构造方法为:

public ThreadPoolExecutor(int arg0, int arg1, long arg2, TimeUnit arg4, BlockingQueue<Runnable> arg5, ThreadFactory arg6, RejectedExecutionHandler arg7) {
      this.ctl = new AtomicInteger(ctlOf(-536870912, 0));
      this.mainLock = new ReentrantLock();
      this.workers = new HashSet();
      this.termination = this.mainLock.newCondition();
      if(arg0 >= 0 && arg1 > 0 && arg1 >= arg0 && arg2 >= 0L) {
         if(arg5 != null && arg6 != null && arg7 != null) {
            this.corePoolSize = arg0;
            this.maximumPoolSize = arg1;
            this.workQueue = arg5;
            this.keepAliveTime = arg4.toNanos(arg2);
            this.threadFactory = arg6;
            this.handler = arg7;
         } else {
            throw new NullPointerException();
         }
      } else {
         throw new IllegalArgumentException();
      }
   }

2)newSingleThreadScheduledExecutor()可简单的理解只有一个线程的调度线程池。可以看到其实还是使用的ThreadPoolExecutor类对象,虽然有点区别,但大致可以理解为newFixedThreadPool(int arg)。

 

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

三、newScheduledThreadPool(int arg)线程池结构:

先看源码:其中队列使用的是DelayedWorkQueue(详见线程池总结2),定时调度任务由此队列实现:该queue同时具有PriorityQueue(优先级大的元素会放到队首)和DelayQueue(队列里第一个元素的getDelay返回值大于0时,则take调用会阻塞)的功能

public ScheduledThreadPoolExecutor(int arg0) {
      super(arg0, Integer.MAX_VALUE, 0L, TimeUnit.NANOSECONDS, new ScheduledThreadPoolExecutor.DelayedWorkQueue());
   }

 

 

四、拓展:

像newCachedThreadPool()这种,用SynchronousQueue这种队列,即消费者生产者模式,队列里同时最多存在一个任务,被取走后新开一个线程任务处理(线程最大数为Integer最大值),才能再添加进来新的。

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

 

五、对比:

1、newFixedThreadPool 和 newSingleThreadExecutor: 请求处理队列可能会耗费无限大的内存。

2、newCachedThreadPool 和 newScheduledThreadPool: 因为线程最大数是 Integer.MAX_VALUE,也会耗费无限大内存。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值