线程池的简单认识

线程池的基本使用

为什么要用线程池

  • 线程生命名周期的开销非常高
  • 资源消耗,活跃的线程数越多,消耗的资源越多,尤其是内存。
  • 线程复用

JDK为我们提供了哪些支持

Executor框架

类图1

  • Executor 定义execute接口。
  • ExecutorService 对外接口,主要使用这个来引用一个线程池。
  • ThreadPoolExecutor 线程池核心实现类
  • Executors 工厂类,通过创建不同的ThreadPoolExecutor实现不同功能的线程池,类似于这样创建 ExecutorService pool = Executors.c=newXXXPool(...)

    • 常用池种类
      • 线程数量固定
      • 线程数量动态
      • 单一线程
      • 按时间计划,依次执行的池。
  • 线程池的几种状态

    • RUNNING 正常运行状态
    • SHUTDOWN 不接受新任务,处理任务队列中的任务
    • STOP 不接受任务,尝试中断任务队列中的任务
    • TIDYING 线程池为空
    • TERMINATED 线程池关闭
  • 线程池原理
    • 生产者消费者 模式
    • HashSet<Worker> workers 保存已经创建了的线程。
    • BlockingQueue workQueue 保存需要执行的任务,任务队列的规模是无限大的。
    • ctl AtomicInteger 以位运算的方式打包封装了当前线程池ThreadPoolExecutor对象的状态和活动线程数两个数据

几种不同的线程池比较

线程池保存任务的QUEUE最大线程数
newFixedThreadPoolLinkedBlockingQueue用户指定
newCachedThreadPoolSynchronousQueueInteger.MAX_VALUE
newScheduledThreadPoolDelayedWorkQueueInteger.MAX_VALUE
newSingleThreadExecutorLinkedBlockingQueue1个

注: BlockingQueue介绍

  • ArrayBlockingQueue
    • 使用数组保存数据
    • ReentrantLock 单锁双条件、notEmpty、notFull
    • 用户指定容量 capacity , 用户指定 boolean fair 是否是公平锁
  • LinkedBlockingQueue
    • 使用Node保存数据
    • 默认大小Int.max
    • 使用了两个锁 putLock-notFull、takeLock-notEmpty,双锁双条件
  • DelayQueue
    • 容量无界
    • 单锁单条件 takeLock-notEmpty
    • 实际上是对优先级队列PriorityQueue类的一个封装
    • 对放入的元素有要求 <E extends Delayed>
  • SynchronousQueue
    • 没用容量概念
    • 内部类TransferQueue和TransferStack
    • 一个元素只有take和put都被阻塞的时候才会互相唤醒,即队列中只会有一个元素。
    • 阻塞机制 使用的是 LockSupport的park()和unPark()方法。

线程池及其核心代码分析

Yonah-潇的博客
三石·道的博客 上中下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值