文章目录

  • 一、线程池阻塞队列
  • 二、拒绝策略
  • 三、使用 ThreadPoolExecutor 自定义线程池参数

一、线程池阻塞队列


线程池阻塞队列是线程池创建的第 555 个参数 : BlockingQueue<Runnable> workQueue ;

    public ThreadPoolExecutor(int corePoolSize,                  // 核心线程数 , 这些线程基本不会被销毁int maximumPoolSize,              // 最大线程数 , 线程池能创建的最大线程数量long keepAliveTime,                 // 空闲情况下 , 非核心线程存活时间TimeUnit unit,                  // 空闲时间单位BlockingQueue<Runnable> workQueue,// 任务的阻塞队列 ★ThreadFactory threadFactory,       // 创建线程的工厂类RejectedExecutionHandler handler) // 拒绝策略

线程池阻塞队列 : 线程池中的阻塞队列 , 同一时刻 , 只能有 111 个线程访问队列 , 执行任务 入队 / 出队 操作 ; 队列都是 FIFO 先进先出 ;

  • 阻塞队列相关概念 :

    • 大小边界 :

      • 有界 : 阻塞队列 大小有限制 , 不是无限大的 ;
      • 无界 : 阻塞队列 理论上无限大 , 比如设置成 Integer.MAX_VALUE ;
    • 队列已满 : 只能出队 , 不能入队 ; 入队操作需阻塞等待 ;
    • 队列为空 : 只能入队 , 不能出队 ; 出队操作需要等待 ;
  • ArrayBlockingQueue : 有界阻塞队列 , 需要 指定阻塞队列大小 ;

  • LinkedBlockingQueue : 无界阻塞队列 , 基于链表的阻塞队列 ;

    • Executors.newCachedThreadPool()Executors.newFixedThreadPool(10) 方法创建的线程池 , 使用的是该阻塞队列 ;
  • SynchronousQueue : 队列 不存储元素 , 后一个 Runnable 任务入队 , 必须等到前一个任务执行完毕才可以 , 否则会一直阻塞等待 ;

    • Executors.newCachedThreadPool() 方法创建的线程池 , 使用的是该阻塞队列 ;
  • PriorityBlockingQueue : 有优先级的阻塞队列 ;

阻塞队列吞吐量 : SynchronousQueue > LinkedBlockingQueue > ArrayBlockingQueue ;

二、拒绝策略


线程池拒绝策略是线程池创建的第 777 个参数 : RejectedExecutionHandler handler ;

    public ThreadPoolExecutor(int corePoolSize,                  // 核心线程数 , 这些线程基本不会被销毁int maximumPoolSize,              // 最大线程数 , 线程池能创建的最大线程数量long keepAliveTime,                 // 空闲情况下 , 非核心线程存活时间TimeUnit unit,                  // 空闲时间单位BlockingQueue<Runnable> workQueue,// 任务的阻塞队列 ThreadFactory threadFactory,        // 创建线程的工厂类RejectedExecutionHandler handler) // 拒绝策略 ★

线程池拒绝策略 : 如果核心线程 , 非核心线程都在执行任务 , 阻塞队列是有界的 , 也满了 , 此时线程池如果再添加任务 , 就会触发如下拒绝策略 ;

  • DiscardPolicy : 丢弃任务 ;
  • DiscardOldestPolicy : 丢弃队头的最旧的任务 ;
  • AbortPolicy : 抛出异常 , 这也是默认方式 ;
  • CallerRunsPolicy : 调用者自行处理 ;

线程池默认的拒绝策略是 抛出异常 方式 ;

    private static final RejectedExecutionHandler defaultHandler =new AbortPolicy();

三、使用 ThreadPoolExecutor 自定义线程池参数


创建 111 个线程池 , 核心线程数是 222 , 最大线程数是 333 , 则非核心线程 0 ~ 1 个 , 非核心线程最大空闲存活时间 60 秒 , 阻塞队列最大存放 10 个元素 , 拒绝策略设置为抛出异常方式 , 如果阻塞队列装满 , 再次尝试执行新任务时 , 会抛出异常 ;

代码示例 :

import java.util.concurrent.*;public class Main {public static void main(String[] args) {ExecutorService executorService = new ThreadPoolExecutor(2,                          // 核心线程数 23,                      // 最大线程数 3, 非核心线程 0 ~ 1 个60,                        // 非核心线程最大空闲存活时间 60 秒TimeUnit.SECONDS,new ArrayBlockingQueue<>(10),   // 阻塞队列, 最大存放 10 个元素Executors.defaultThreadFactory(),       // 线程工厂new ThreadPoolExecutor.AbortPolicy()    // 决绝策略, 如果执行任务失败, 抛出异常);for (int i = 0; i < 20; i ++) {executorService.execute(new Task(i));}}static class Task implements Runnable {/*** 记录线程的索引 0 ~ 99*/private int i = 0;public Task(int i) {this.i = i;}@Overridepublic void run() {System.out.println("线程 ID : " + Thread.currentThread().getName() + " , 线程索引 : " + i);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}

执行结果 : 这里线程最大执行到了 121212 , 也就是从 000 开始计数 , 执行了 131313 个任务 , 其中 333 个线程池各自执行一个任务 , 阻塞队列存放 101010 个任务 , 再次尝试将第 141414 个任务放入阻塞队列时 , 报出 java.util.concurrent.RejectedExecutionException 异常 , 但是队列中的 101010 个任务也正常执行完毕 ;

线程 ID : pool-1-thread-2 , 线程索引 : 1
线程 ID : pool-1-thread-3 , 线程索引 : 12
线程 ID : pool-1-thread-1 , 线程索引 : 0
Exception in thread "main" java.util.concurrent.RejectedExecutionException:
Task Main$Task@5cad8086 rejected from java.util.concurrent.ThreadPoolExecutor@6e0be858
[Running, pool size = 3, active threads = 3, queued tasks = 10, completed tasks = 0]at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2047)at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823)at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1369)at Main.main(Main.java:16)
线程 ID : pool-1-thread-3 , 线程索引 : 2
线程 ID : pool-1-thread-1 , 线程索引 : 4
线程 ID : pool-1-thread-2 , 线程索引 : 3
线程 ID : pool-1-thread-1 , 线程索引 : 5
线程 ID : pool-1-thread-2 , 线程索引 : 7
线程 ID : pool-1-thread-3 , 线程索引 : 6
线程 ID : pool-1-thread-1 , 线程索引 : 9
线程 ID : pool-1-thread-2 , 线程索引 : 8
线程 ID : pool-1-thread-3 , 线程索引 : 10
线程 ID : pool-1-thread-2 , 线程索引 : 11

【Java 并发编程】线程池机制 ( 线程池阻塞队列 | 线程池拒绝策略 | 使用 ThreadPoolExecutor 自定义线程池参数 )相关推荐

  1. Java并发编程之锁机制之LockSupport工具

    关于文章涉及到的jdk源码,这里把最新的jdk源码分享给大家----->jdk源码 前言 在上篇文章<Java并发编程之锁机制之AQS(AbstractQueuedSynchronizer ...

  2. Java并发编程与技术内幕:线程池深入理解

    林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要: 本文主要讲了Java当中的线程池的使用方法.注意事项及其实现源码实现原理,并辅以实例加 ...

  3. Java 并发编程解析 | 如何正确理解Java领域中的锁机制,我们一般需要掌握哪些理论知识?

    苍穹之边,浩瀚之挚,眰恦之美: 悟心悟性,善始善终,惟善惟道! -- 朝槿<朝槿兮年说> 写在开头 提起Java领域中的锁,是否有种"道不尽红尘奢恋,诉不完人间恩怨"的 ...

  4. 【面试】Java 并发编程

    并发编程 1. 进程与线程的区别 线程上下文切换比进程上下文切换快的原因 谈谈你对守护线程的理解 守护线程和用户线程有什么区别? 线程的 run() 和 start() 有什么区别? 2. 多线程与单 ...

  5. 8w字 | Java并发编程 全套功法

    介绍:CSDN统计字数:77153字,Java多线程从入门到精通,由浅入深.[建议收藏!] ❤️❤️❤️❤️❤️❤️ 点击主页发现更多好文❤️❤️❤️❤️❤️❤️ 文章目录 引言 什么是进程,线程? ...

  6. Java并发编程:阻塞队列

    2019独角兽企业重金招聘Python工程师标准>>> 本文先讲述一下java.util.concurrent包下提供主要的几种阻塞队列,然后分析了阻塞队列和非阻塞队列的中的各个方法 ...

  7. 【Java 并发编程】线程池机制 ( ThreadPoolExecutor 线程池构造参数分析 | 核心线程数 | 最大线程数 | 非核心线程存活时间 | 任务阻塞队列 )

    文章目录 前言 一.ThreadPoolExecutor 构造参数 二.newCachedThreadPool 参数分析 三.newFixedThreadPool 参数分析 四.newSingleTh ...

  8. 【Java 并发编程】线程池机制 ( 线程池示例 | newCachedThreadPool | newFixedThreadPool | newSingleThreadExecutor )

    文章目录 前言 一.线程池示例 二.newCachedThreadPool 线程池示例 三.newFixedThreadPool 线程池示例 三.newSingleThreadExecutor 线程池 ...

  9. 【Java 并发编程】线程池机制 ( 线程池执行任务细节分析 | 线程池执行 execute 源码分析 | 先创建核心线程 | 再放入阻塞队列 | 最后创建非核心线程 )

    文章目录 一.线程池执行任务细节分析 二.线程池执行 execute 源码分析 一.线程池执行任务细节分析 线程池执行细节分析 : 核心线程数 101010 , 最大小成熟 202020 , 非核心线 ...

最新文章

  1. 特斯拉遇上 CPU:程序员的心思你别猜
  2. MATLAB读取文本文件----textread
  3. python自带库处理excel-python处理excel之第三方库openpyxl
  4. TCP/IP协议(二)tcp/ip基础知识
  5. Android系统如何实现UI的自适应
  6. Jenkins连接TFS出现错误:“jenkins com.microsoft.tfs.core.exceptions.TECoreException”的问题收集...
  7. 微信小程序轮播图中间变大_微信小程序实现带放大效果的轮播图
  8. 【Java】输入三角形的三边长,求三角形的面积
  9. Nvelocity 第二章 注释语法
  10. VS2015正确卸载方法,亲测
  11. Winform微信扫码支付
  12. log10/log2--求常用对数/以2为底的对数
  13. [python爬虫之路day4]:xpath基本知识lxml结合xpath进行数据分析爬取豆瓣电影
  14. Pascal voc 数据集xml格式解析
  15. Arduino ESP8266利用定时器中断控制LED闪烁示例程序
  16. php 插件推荐,Typecho实用插件推荐(一)
  17. Mac自带FTP工具用法
  18. NSGA-3优化算法介绍及案例实现(三个测试函数DTLZ1、DTLZ2和DTLZ3)
  19. hyu 1698 Just a Hook
  20. 2018年我国互联网网络安全态势综述

热门文章

  1. 如何为file增加文件类型的识别
  2. language wars
  3. 极虎病毒创造四个“之最”
  4. Sliverlight Slide 的左右滑动
  5. LWIP再探----内存池管理
  6. python接口自动化(二十四)--unittest断言——中(详解)
  7. jedis操作redis(一)
  8. 一个经典的字母排列算法
  9. (Lesson2)根据类名称和属性获得元素-JavaScript面向对象
  10. java 操作数据库