【并发编程】- ThreadPoolExecutor篇
Executor框架
Executor框架的两级调度模型(基于HotSpot)- 在上层,Java多线程程序通常把应用分解为若干个任务,然后使用用户级的调度器(
Executor框架)将这些任务映射为固定数量的线程; - 在底层,操作系统内核将这些线程映射到硬件处理器上。
任务的两级调度模型
- 在上层,Java多线程程序通常把应用分解为若干个任务,然后使用用户级的调度器(
- 结构
- 3大部分
- 任务。包括被执行任务需要实现的接口:
Runnable接口或Callable接口。 - 任务的执行。包括任务执行机制的核心接口
Executor,以及继承自Executor的ExecutorService接口。Executor框架有两个关键类实现了ExecutorService接口(ThreadPoolExecutor和ScheduledThreadPoolExecutor)。 - 异步计算的结果。包括接口
Future和实现Future接口的FutureTask类。
- 任务。包括被执行任务需要实现的接口:
类与接口
- 3大部分
- 成员
ThreadPoolExecutor:通常使用工厂类Executors来创建。SingleThreadExecutor- 使用单个线程,适用于
需要保证顺序地执行各个任务;并且在任意时间点,不会有多个线程是活动的应用场景。
- 使用单个线程,适用于
FixedThreadPool- 使用固定线程数,适用于
负载比较重的服务器。
- 使用固定线程数,适用于
CachedThreadPool- 会根据需要创建新线程,大小无界,适用于
执行很多的短期异步任务的小程序,或者是负载较轻的服务器。
- 会根据需要创建新线程,大小无界,适用于
ScheduledThreadPoolExecutor:通常使用工厂类Executors来创建.- 包含若干个线程的ScheduledThreadPoolExecutor。
- 创建固定个数线程,适用于需要多个后台线程执行周期任务,同时为了满足资源管理的需求而需要限制后台线程的数量的应用场景。
- 只包含一个线程的ScheduledThreadPoolExecutor。
- 创建单个线程,适用于需要单个后台线程执行周期任务,同时需要保证顺序地执行各个任务的应用场景。
- 包含若干个线程的ScheduledThreadPoolExecutor。
Future接口- FutureTask实现类,表示异步计算的结果。
Runnable接口和Callable接口Runnable不会返回结果。Callable可以返回结果。
ThreadPoolExecutor详解- 4个组件
corePool:核心线程池的大小。maximumPool:最大线程池的大小。BlockingQueue:用来暂时保存任务的工作队列。RejectedExecutionHandler:当ThreadPoolExecutor已经关闭或ThreadPoolExecutor已经饱和时(达到了最大线程池大小且工作队列已满),execute()方法将要调用的Handler。
- 3种ThreadPoolExecutor
FixedThreadPool- 可重用固定线程数的线程池。
- 使用无界队列
LinkedBlockingQueue作为线程池的工作队列(队列的容量为Integer.MAX_VALUE。
SingleThreadExecutor- 使用单个
worker线程的Executor。 - 使用无界队列
LinkedBlockingQueue作为线程池的工作队列(队列的容量为Integer.MAX_VALUE。
- 使用单个
CachedThreadPool- 会根据需要创建新线程的线程池。
- 使用无容量的SynchronousQueue作为线程池的工作队列。
ScheduledThreadPoolExecutor详解- ScheduledThreadPoolExecutor继承自ThreadPoolExecutor。它主要用来在给定的延迟之后运行任务,或者定期执行任务
- ScheduledThreadPoolExecutor的执⾏主要分为两⼤部分
- 当调⽤ScheduledThreadPoolExecutor的scheduleAtFixedRate()fang法或者scheduleWith-FixedDelay()方法时,会向ScheduledThreadPoolExecutor的DelayQueue添加一个实现了RunnableScheduledFutur接⼝的ScheduledFutureTask
- 线程池中的线程从DelayQueue中获取ScheduledFutureTask,然后执行任务
ScheduledThreadPoolExecutor 运行机制图
Java里的阻塞队列
- JDK 7提供了7个阻塞队列
- ArrayBlockingQueue:一个由数组结构组成的有界阻塞队列。
- LinkedBlockingQueue:一个由链表结构组成的有界阻塞队列。
- PriorityBlockingQueue:一个支持优先级排序的无界阻塞队列。
- DelayQueue:一个使用优先级队列实现的无界阻塞队列。
- SynchronousQueue:一个不存储元素的阻塞队列。
- LinkedTransferQueue:一个由链表结构组成的无界阻塞队列。
- LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列。
- JDK 7提供了7个阻塞队列
ArrayBlockingQueue:数组有界阻塞队列,默认线程非公平的访问队列,公平性是使用可重入锁实现
public ArrayBlockingQueue(int capacity, boolean fair) {
if (capacity <= 0)
throw new IllegalArgumentException();
this.items = new Object[capacity];
lock = new ReentrantLock(fair);
notEmpty = lock.newCondition();
notFull = lock.newCondition();
}
- LinkedBlockingQueue:链表有界阻塞队列,默认长度Integer.Max_VALUE
- PriorityBlockingQueue:是一个支持优先级的无界阻塞队列。默认情况下元素采取用然顺序升序排列
- DelayQueue是一个支持延时获取元素的无界阻塞队列,使用PriorityQueue来实现
- 应用场景:
- 缓存系统的设计:可以用DelayQueue保存缓存元素的有效期,使用一个线程循环查询DelayQueue,一旦能从DelayQueue中获取元素时,表示缓存有效期到了
- 定时任务调度:使用DelayQueue保存当天将会执行的任务和执行时间,一旦从DelayQueue中获取到任务就开始执行,比如TimerQueue就是使用DelayQueue实现的
- 应用场景:
- SynchronousQueue:是一个不存储元素的阻塞队列。它支持公平访问队列,默认情况下线程采用非公平性策略访问队列。
- LinkedTransferQueue:是一个由链表结构组成的无界阻塞TransferQueue队列。
- 比其他阻塞队列多了tryTransfer和transfer方法
- 当前有消费者正在等待接收元素,transfer方法可以把生产者传入的元素立刻transfer(传输)给消费者,没有消费者在等待接收元素时,将元素存放在队列的tail节点,并等到该元素被消费者消费了才返回
- 同上,试探性是否能直接传给消费者,若无消费者,返回false。
- 比其他阻塞队列多了tryTransfer和transfer方法
- LinkedBlockingDeque:是一个由链表结构组成的双向阻塞队列
【并发编程】- ThreadPoolExecutor篇的更多相关文章
- [并发编程] -- ThreadPoolExecutor篇
Executor框架 Executor框架的两级调度模型(基于HotSpot) 在上层,Java多线程程序通常把应用分解为若干个任务,然后使用用户级的调度器(Executor框架)将这些任务映射为固定 ...
- Python并发编程理论篇
Python并发编程理论篇 前言 其实关于Python的并发编程是比较难写的一章,因为涉及到的知识很复杂并且理论偏多,所以在这里我尽量的用一些非常简明的语言来尽可能的将它描述清楚,在学习之前首先要记住 ...
- python之并发编程初级篇8
一.进程理论 1)进程介绍 .什么是进程 一个正在进行的过程,或者说是一个程序的运行过程 其实进程是对正在运行的程序的一种抽象/概括的说法 进程的概念起源操作系统,进程是操作最核心的概念之一 操作系统 ...
- java架构《并发编程框架篇 __Disruptor》
Disruptor入门 获得Disruptor 可以通过Maven或者下载jar来安装Disruptor.只要把对应的jar放在Java classpath就可以了. 基本的事件生产和消费 我们从 ...
- python之并发编程进阶篇9
一.守护进程和守护线程 1)守护进程的概念 什么是守护进程: 守护: 在主进程代码结束情况下,就立即死掉 守护进程本质就是一个子进程,该子进程守护着主进程 为何要用守护进程 守护进程本质就是一个子进程 ...
- Java并发编程--ThreadPoolExecutor
概述 为什么要使用线程池? 合理利用线程池能够带来三个好处.第一:降低资源消耗.通过重复利用已创建的线程降低线程创建和销毁造成的消耗.第二:提高响应速度.当任务到达时,任务可以不需要等到线程创建就能立 ...
- JAVA 并发编程-应用篇
提到java多线程不免有些人会头大.非常多概念都是非常理解可是真正到了实战的时候又是不知道怎样操作了.以下就结合实际项目来说说多线程的应用. 业务需求: 举例:批量插入10万条用户的相关活动优惠券 操 ...
- Python3 与 C# 并发编程之~ 线程篇
2.线程篇¶ 在线预览:https://github.lesschina.com/python/base/concurrency/3.并发编程-线程篇.html 示例代码:https://gith ...
- Python 并发编程:PoolExecutor 篇
个人笔记,如有疏漏,还请指正. 使用多线程(threading)和多进程(multiprocessing)完成常规的并发需求,在启动的时候 start.join 等步骤不能省,复杂的需要还要用 1-2 ...
- Python3 与 C# 并发编程之~ 进程篇
上次说了很多Linux下进程相关知识,这边不再复述,下面来说说Python的并发编程,如有错误欢迎提出- 如果遇到听不懂的可以看上一次的文章:https://www.cnblogs.com/dot ...
随机推荐
- 第12.1节 Python os模块导览
os 模块提供了许多与操作系统交互的函数,一定要使用 import os 而不是 from os import * ,这将避免内建的 open() 函数被 os.open() 隐式替换掉,它们的使用方 ...
- OA公文流转系统(未完成)
基本页面比较多,所以就不贴出来了,具体的页面可以自行浏览. 点我进入OA系统浏览界面(未做响应式布局,需电脑端打开) 账号密码: 部门:bumen------bumen 办公室:bangongshi- ...
- 常见SQL注入点判断
sql注入手工检测 SQL注入手工检测 1基本检测 数字型 字符型 搜索型 POST注入 布尔盲注 报错注入 堆叠注入 判断是什么数据库 2绕过技巧 大小写 替换关键字 使用编码 注释和符号 等价函数 ...
- 嘶吼CTF easy calc
进入之后可以看到我们需要输入一个计算式来得到答案,burpsuite进行抓包之后发现页面来自于calc.php 我们直接访问calc.php页面 发现源代码泄露 可以看到当我们没有输入num值的时候就 ...
- vue Export2Excel 导出文件
使用需要引入这些js 在src目录下创建一个文件(vendor)进入Blob.js和Export2Excel.js npm install -S file-saver 用来生成文件的web应用程序 n ...
- uni-app中使用sass
uni-app在创建时,工程目录下会有个uni.scss文件,我们可以直接在里面定制化scss变量. 全局scss中的坑: 1.如果要引用全局外部scss文件,可以考虑在uni.scss这个系统全局s ...
- STL——容器(Map & multimap)的大小
1. Map & multimap 的大小 map.size(); //返回容器中元素的数目 map.empty();//判断容器是否为空, 容器中有内容将会返回 false 代码示例 ...
- centos 7系统安装mysql 8.0
一.关闭防火墙 [root@node01 ~]# systemctl disable firewalld [root@node01 ~]# systemctl stop firewalld [root ...
- 简易CLI
使用C语言实现一个简易的CLI,命令通过模式进行划分,实现效果如下: 代码较为简单,主要是为了方便进行移植,这里就不进行详细的说明了. 代码路径:https://github.com/zhengcix ...
- 测开之数据类型· 第3篇《列表推导式、字典推导式、2种方式创建生成器》
坚持原创输出,点击蓝字关注我吧 作者:清菡 博客:oschina.云+社区.知乎等各大平台都有. 目录 一.列表推导式 二.字典推导式 三.2种方式创建生成器 1.生成器表达式 2.函数里面,通过 y ...