并发编程工具集——线程池(二十六)

关于创建对象和线程

  1. 创建对象是在JVM的堆里分配一块儿内存
  2. 创建线程需要调用操作系统内核的API,然后操作系统要为线程分配一系列的资源,成本颇高,所以线程频繁创建和销毁消耗性能会很高,应当避免

线程池与其他池化资源的区别

  1. 一般意义上的池化资源,当你需要资源的时候就调用 acquire() 申请资源,用完之后调用 release() 释放资源。
  2. Java 提供的线程池里面压根就没有申请线程和释放线程的方法。

线程池的简易实现

  1. 目前线程池普遍使用生产者-消费者模式
    • 在 MyThreadPool 的内部,维护了一个阻塞队列 workQueue 和一组工作线程,工作线程的个数由构造函数中的 poolSize 来指定。用户通过调用 execute() 方法来提交 Runnable 任务,execute() 方法的内部实现仅仅是将任务加入到 workQueue 中。MyThreadPool 内部维护的工作线程会消费 workQueue 中的任务并执行任务,相关的代码就是代码①处的 while 循环。
    • 简要实现

 

如何使用 Java 中的线程池(线程池的七个参数)

  1. Java 提供的线程池相关的工具类中,最核心的是 ThreadPoolExecutor,通过名字你也能看出来,它强调的是 Executor,而不是一般意义上的池化资源。
  2. ThreadPoolExecutor 的构造函数有七个参数
    • corePoolSize:线程池保有的最小线程数。
    • maximumPoolSize::表示线程池创建的最大线程数。
    • keepAliveTime & unit:如果一个线程空闲了keepAliveTime & unit这么久,而且线程池的线程数大于 corePoolSize ,那么这个空闲的线程就要被回收了。
    • workQueue:工作队列
    • threadFactory:自定义如何创建线程,比如自定义线程名称
    • handler:自定义任务的拒绝策略(如果线程池中所有的线程都在忙碌,并且工作队列也满了(前提是工作队列是有界队列),那么此时提交任务,线程池就会拒绝接收。)总共四种拒绝策略
      1. CallerRunsPolicy:提交任务的线程自己去执行该任务。
      2. AbortPolicy:默认的拒绝策略,会 throws RejectedExecutionException。
      3. DiscardPolicy:直接丢弃任务,没有任何异常抛出。
      4. DiscardOldestPolicy:丢弃最老的任务,其实就是把最早进入工作队列的任务丢弃,然后把新任务加入到工作队列。
    • Java 在 1.6 版本还增加了 allowCoreThreadTimeOut(boolean value) 方法,它可以让所有线程都支持超时,这意味着如果项目很闲,就会将项目组的成员都撤走。

 

线程池注意事项

  1. 考虑到 ThreadPoolExecutor 的构造函数比较复杂,所以 Java 并发包里提供了一个线程池的静态工厂类 Executors,利用 Executors 你可以快速创建线程池。
  2. 但是目前大厂都不让使用ExecutorsExecutors 提供的很多方法默认使用的都是无界的 LinkedBlockingQueue,高负载情境下,无界队列很容易导致 OOM,而 OOM 会导致所有请求都无法处理,这是致命问题。所以强烈建议使用有界队列。
  3. 谨慎使用拒绝策略:使用有界队列,当任务过多时,线程池会触发执行拒绝策略,线程池默认的拒绝策略会 throw RejectedExecutionException 这是个运行时异常,对于运行时异常编译器并不强制 catch 它,所以开发人员很容易忽略。因此默认拒绝策略要慎重使用。如果线程池处理的任务非常重要,建议自定义自己的拒绝策略;并且在实际工作中,自定义的拒绝策略往往和降级策略配合使用。
  4. 注意异常处理:例如通过 ThreadPoolExecutor 对象的 execute() 方法提交任务时,如果任务在执行的过程中出现运行时异常,会导致执行任务的线程终止;不过,最致命的是任务虽然异常了,但是你却获取不到任何通知,这会让你误以为任务都执行得很正常。虽然线程池提供了很多用于异常处理的方法,但是最稳妥和简单的方案还是捕获所有异常并按需处理

 

  • 28
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值