线程池--学习笔记

JDK里的几种线程池
先看下一个ThreadPoolExecutor通用的构造函数,有8个参数。

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

下面介绍下每个参数的具体含义
corePoolSize:线程池的基本大小,即在没有任务执行的情况时线程池的大小。
maximumPoolSize: 线程池的最大大小,,表示可同时活动的线程数量的上限。
keepAliveTime: 线程的存活时间,如果某个线程的空闲时间超过了存活时间并且当前线程池大小大于corePoolSize时,那么将被标记为可回收。
TimeUnit unit:存活时间的时间单位
BlockingQueue workQueue: 如果请求的到达速率超过了线程池的处理速率,那么新到来的线程将在该队列中等待。基本的任务排队方法有3中:无界队列,有界队列和同步移交。
ThreadFactory :线程工厂,当线程池需要创建一个线程时,通过线程工厂方法创建一个新的,非守护的线程,并且不包含特殊的配置信息。ThreadFactory 中只定义一个方法Thread newThread(Runnable r);,每当线程池需要创建一个新的线程时都会调用这个方法。
RejectedExecutionHandler : 当有界队列被填满同时线程池里的线程数达到maximumPoolSize后,饱和策略才会开始发挥作用。


线程池的运行过程

  public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        int c = ctl.get();
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        else if (!addWorker(command, false))
            reject(command);
    }

当一个任务被提交到线程池时,如果当前线程池中的线程数小于corePoolSize,则创建一个线程来处理该请求。即使其他工作线程处于空闲状态。如果当前线程池中的线程数大于corePoolSize同时小于maximumPoolSize时,则先将任务放入阻塞队列中,当在队列满的时候会创建新的线程。当线程池中的数量达到maximumPoolSize,队列满的时候。启动饱和策略来处理任务。

两种常用的线程池

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

该线程池将corePoolSize和maximumPoolSize设置为参数中指定的值,而且创建的线程不会超时。使用一个无界的LinkedBlockingQueue。如果所有的线程都处于忙碌状态,那么任务将在队列中等候。如果任务持续快速的到达,并且超过了线程池的处理速度,那么队列将会无限制的增加。

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

该线程池将corePoolSize设置为0,maximumPoolSize设置为Integer.MAX_VALUE。超时时间为1分钟。使用SynchronousQueue来避免任务排队以及直接将任务从生产者移交给工作者线程。SynchronousQueue不是一个真正的队列,而是一种在线程之间进行移交的机制。要将任务放入SynchronousQueue中,必须有另外一个线程正在等待接收这个任务。当有线程空闲时间超过1分钟时则会被回收。

饱和策略:
AbortPolicy: 中止策略是默认的饱和策略,该饱和策略将抛出未检查的RejectExecutionException。调用者可以捕获这个异常,然后根据自己的需求编写自己的处理逻辑。
DiscardPolicy: 抛弃策略。当新的任务无法保存在队列中等待执行时,抛弃策略会悄悄抛弃该任务。
DiscardOldestPolicy: 抛弃最旧的策略。 当新的任务无法保存在队列中等待执行时,该策略会抛弃下一个将被执行的任务,然后重新提交新的任务。
CallerRunsPolicy: 调用者运行策略,该策略实现一种调节机制,既不会抛弃任务,也不会抛出异常,而是将某些任务回退到调用者,从而降低新的任务流量。它不会在线程池的某个线程执行新提交的任务,而是在一个调用了execute时的主线程中执行。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值