线程池创建

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

参数含义

  • corePoolSize :表示线程池中核心线程数
  • maximumPoolSize :表示线程池中能创建的最大线程数
  • keepAliveTime :表示空闲线程的存活时间
  • TimeUnit unit :表示keepAliveTime的单位
  • workQueue:用于缓存任务的阻塞队列
  • threadFactory :指定创建线程的工厂
  • handler:饱和策略(拒绝策略)

工作原理

如果有空闲线程,则直接执行该任务;
如果没有空闲线程,且当前运行的线程数少于corePoolSize,则创建新的线程执行该任务;
如果没有空闲线程,且当前的线程数等于corePoolSize,同时阻塞队列未满,则将任务放入阻塞队列,而不添加新的线程;
如果没有空闲线程,且阻塞队列已满,同时线程池中的线程数小于maximumPoolSize ,则创建新的线程执行任务;
如果没有空闲线程,且阻塞队列已满,同时池中的线程数等于maximumPoolSize ,则根据构造函数中的 handler 指定的策略来拒绝新的任务。

阻塞队列

SynchronousQueue

(1)没有容量大小,即无缓冲的阻塞队列;

(2)每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态;

(3)底层实现有两种

非公平的堆栈,遵循先进后出,每次从栈顶取元素;

公平的队列,遵循先进先出,每次从队列头取元素。                                                                 

(4)使用CAS实现线程的安全访问

Executors.newCachedThreadPool 使用了这个队列。

ArrayBlockingQueue

(1)内部维护了一个定长数组,在初始化的时候,必须传入一个容量大小的值;                        

(2)生产者和消费者使用的是同一把锁ReentrantLock,使用公平锁还是非公平锁,在创建ArrayBlockingQueue时可以指定,默认是非公平锁。

(3)当队列为空,消费者线程被阻塞;当队列装满,生产者线程被阻塞;使用Condition的方法来同步和通信:await()和signal()

lock = new ReentrantLock(fair);

notEmpty = lock.newCondition();

notFull = lock.newCondition();

LinkedBlockingQueue

(1)内部维护的是一个链表结构。在生产和消费的时候,需要创建Node对象进行插入或移除,大批量数据的系统中,其对于GC的压力会比较大。

(2)LinkedBlockingQueue有默认的容量大小为:Integer.MAX_VALUE,也可以传入参数指定容量大小

(3)LinkedBlockingQueue中的锁是分离的,生产者的锁PutLock,消费者的锁takeLock。在高并发的情况下生产者和消费者可以并行地操作队列中的数据,以此来提高整个队列的并发性能。

(4)put方法将一个对象放到队列尾部,在队列满的时候会阻塞直到有队列成员被消费,take方法从head取一个对象,在队列为空的时候会阻塞,直到有队列成员被放进来。

DelayedWorkQueue

(1)通过数组实现的堆来存储任务

(2)ScheduledThreadPoolExecutor阻塞队列使用的都是DelayedWorkQueue;

(3)可以延迟执行任务,比如说一定时间后执行任务或是每隔一定的时间执行一次任务。

PriorityBlockingQueue

(1)按照优先级进行内部元素排序的无界阻塞队列。队列中的元素必须实现 Comparable 接口,通过实现compareTo()方法进行排序。优先级最高的元素始终排在队列的头部;

(2)通过ReentrantLock来保证线程并发安全,内部控制线程同步采用公平锁。

(3)内部使用二叉树堆维护元素优先级,使用数组作为元素存储的数据结构,数组是可扩容的。

饱和策略,拒绝策略

handler,当 workQueue 已满,且池中的线程数达到 maximumPoolSize 时,线程池拒绝添加新任务时采取的策略。(可以不指定)

hreadPoolExecutor.AbortPolicy()

丢弃任务,并抛出RejectedExecutionException异常,默认策略。

ThreadPoolExecutor.DiscardPolicy()   

丢弃任务,但是不抛出异常。

ThreadPoolExecutor.CallerRunsPolicy()   

由向线程池提交任务的线程来执行该任务

ThreadPoolExecutor.DiscardOldestPolicy()   

抛弃最旧的任务(最先提交而没有得到执行的任务)

线程池的关闭

关闭线程池,可以通过shutdown和shutdownNow两个方法

原理:遍历线程池中的所有线程,然后依次中断

1、shutdownNow首先将线程池的状态设置为STOP,然后尝试停

止所有的正在执行和未执行任务的线程,并返回等待执行任务的

列表;

2、shutdown只是将线程池的状态设置为SHUTDOWN状态,然

后中断所有没有正在执行任务的线程。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值