JDK并发包二
JDK并发包二
线程复用——线程池
在线程池中,总有那么几个活跃的线程,当程序需要线程时可以从池子中随便拿一个控线程,当程序执行完毕,线程不关闭,而是将这个线程退会到池子,等待使用。
JDK提供了一套Executor框架,可以有效进行线程控制。ThreadPoolExecutor表示一个线程池,Executors类相当与线程池工厂,通过Executors可以获得一个拥有特定功能的线程池。
Executors框架提供了各类线程池,主要有下面工厂方法
public static ExecutorService newFixedThreadPool(int nThreads);
public static ExecutorService newSingleThreadExecutor() ;
public static ExecutorService newCachedThreadPool();
public static ScheduledExecutorService newSingleThreadScheduledExecutor();
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize);
- newFixedThreadPool()此方法返回一个有固定线程数量的线程池。当一个新的任务提交时,线程中若有空闲线程则立即执行,若无则会暂存在一个任务队列中,待有线程空闲时,再进行处理。
- newSingleThreadExecutor()此方法返回一个只有一个线程的线程池,有新任务提交到线程池中会被安排到任务队列中,等待执行。
- newCachedThreadPool()此方法返回一个根据实际情况调整线程数量的线程池,线程池中线程的数量不确定,若有新任务,线程池中有空闲线程,就复用空闲线程,如果没有就重新开启一个新的线程执行。
- newSingleThreadScheduledExecutor()此方法返回一个ScheduledExecutorService对象,线程池大小为1,ScheduledExecutorService可以周期执行某个任务
- newScheduledThreadPool() 此方法返回一个ScheduledExecutorService对象 但可以指定线程数量。
- 固定任务
public static void main(String[] args) {
MyTesk myTesk = new MyTesk();
ExecutorService executorService = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
executorService.submit(myTesk);
}
executorService.shutdown();
}
static class MyTesk implements Runnable {
@Override
public void run() {
System.out.println(System.currentTimeMillis() + Thread.currentThread().getName() + "线程执行");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
计划任务
ScheduledExecutorService有三个重要的方法来执行计划任务
schedule(Runnable command,long delay, TimeUnit unit) ;
scheduleAtFixedRate(Runnable command,
long initialDelay,
long period,
TimeUnit unit);scheduleWithFixedDelay(Runnable command,
long initialDelay,
long delay,
TimeUnit unit);
schedule()会在设定的延时后执行一次。
scheduleAtFixedRate()会在设定的延时(initialDelay)之后按照(period)为周期进行执行。若在下一个周期开始时当前任务未完成,则不会执行直到当前任务完成。若当前任务时间超出任务周期,则每次任务执行完就会立刻执行下一个任务。
scheduleWithFixedDelay()会在设定的延时(initialDelay)之后执行任务,任务完成后间隔(delay)进行下一次执行
如果有任务抛出异常则所有任务会全部停止执行
核心线程池内部实现
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
ThreadPoolExecutor的构造方法
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
- corePoolSize 指定了线程池中线程的数量
- maximumPoolSize 指定了线程池中最大线程数量
- keepAliveTime 当线程池中线程数量超过corePoolSize后多余线程的存活时间
- unit keepAliveTime的时间单位
- workQueue 任务队列被提交,但未被执行的任务的任务
- threadFactory 线程工厂,默认即可
- handler 拒绝策略
workQueue 任务队列
直接提交队列
由SynchronousQueue对象提供,SynchronousQueue没有容量 每一个插入操作都要等待一个删除操作,每一个删除都要等待对应的插入操作。使用SynchronousQueue提交的任务不会被真实保存,而是将新任务提交给线程执行,如果没有空闲线程就会试图创建新线程。如果进程数量已到达最大值,则执行拒绝策略。
有界任务队列
使用ArrayBlockingQueue实现,ArrayBlockingQueue(int capacity)capacity表示队列最大容量创建时必须给定当有新任务时,如果有空闲线程,就立即执行。没有则入队等待空闲线程,如果队列已满则尝试创建线程。如果线程数超过maximumPoolSize就会执行拒绝策略
无界任务队列
LinkedBlockingQueue类来实现 与有界相比,不同点在于队列不会满,只要内存资源足够可以一直添加到队列中,直到系统内存耗尽
有限任务队列
PriorityBlockingQueue可实现,它是一个特殊的无界队列,PriorityBlockingQueue可以根据任务的优先级顺序先后执行
总之线程调用逻辑
JDK并发包二的更多相关文章
- Java 并发编程实践基础 读书笔记: 第三章 使用 JDK 并发包构建程序
一,JDK并发包实际上就是指java.util.concurrent包里面的那些类和接口等 主要分为以下几类: 1,原子量:2,并发集合:3,同步器:4,可重入锁:5,线程池 二,原子量 原子变量主要 ...
- Java并发程序设计(四)JDK并发包之同步控制
JDK并发包之同步控制 一.重入锁 重入锁使用java.util.concurrent.locks.ReentrantLock来实现.示例代码如下: public class TryReentrant ...
- Java多线程--JDK并发包(2)
Java多线程--JDK并发包(2) 线程池 在使用线程池后,创建线程变成了从线程池里获得空闲线程,关闭线程变成了将线程归坏给线程池. JDK有一套Executor框架,大概包括Executor.Ex ...
- Java多线程--JDK并发包(1)
Java多线程--JDK并发包(1) 之前介绍了synchronized关键字,它决定了额一个线程是否可以进入临界区:还有Object类的wait()和notify()方法,起到线程等待和唤醒作用.s ...
- 3 JDK并发包
JDK内部提供了大量实用的API和框架.本章主要介绍这些JDK内部功能,主要分为3大部分: 首先,介绍有关同步控制的工具,之前介绍的synchronized就是一种同步控制手段,将介绍更加丰富的多线程 ...
- 第3章 JDK并发包(三)
3.2 线程复用:线程池 一种最为简单的线程创建和回收的方法类似如下代码: new Thread(new Runnable() { @Override public void run() { // d ...
- JDK并发包一
JDK并发包一 同步控制是并发程序必不可少的重要手段,synchronized是一种最简单的控制方法.但JDK提供了更加强大的方法----重入锁 重入锁 重入锁使用java.util.concurre ...
- 第3章 JDK并发包(二)
3.1.2 重入锁的好搭档:Condition条件 它和wait()和notify()方法的作用是大致相同的.但是wait()和notify()方法是和synchronized关键字合作使用的,而Co ...
- Java并发程序设计(五)JDK并发包之线程复用:线程池
线程复用:线程池 一.为什么需要线程池 为了避免系统频繁地创建和销毁线程,使用线程池让线程进行复用.(即创建线程变成了从线程池中获取空闲线程,销毁线程变成了把线程放回线程池中.) 二.JDK对线程池的 ...
随机推荐
- window系统搭建医药后台系统
软件准备: mysql版本: 5.7 jdk版本:1.8 tomcat版本: 9.0 mysql:5.7 第一步:新建Mysql连接 新建Mysql连接 第二步:新建数据库 新建数据库 第三步 ...
- Redis数据结构—跳跃表
目录 Redis数据结构-跳跃表 跳跃表产生的背景 跳跃表的结构 利用跳跃表查询有序链表 Redis跳跃表图示 Redis跳跃表数据结构 小结 Redis数据结构-跳跃表 大家好,我是白泽,最近学校有 ...
- Dom树,什么是dom树?
相信很多初学前端的小伙伴,学了html,css,js之后,欣喜之余还有一丝小傲娇,没有想到那些大佬们口中又 提到了DOM树.你两眼一抹黑,年轻人总是要接受社会的爱(du)护(da). DOM 是 Do ...
- .Net core Worker Service 扩展库
.Net core Worker Service 扩展库,目的为更易控制每一个worker 的运行. 提供根据配置文件对每一个Worker的停止.启动和自动解析注册Worker. 获取配置的方式不限于 ...
- MyBatis 全局配置文件详解(七)
MyBatis 配置文件作用 MyBatis配置文件包含影响 MyBatis 框架正常使用的功能设置和属性信息.它的作用好比手机里的设置图标,点击这个图标就可以帮助我们查看手机的属性信息和设置功能.其 ...
- 2.5if语句
判断(if)语句 目标 开发中的应用场景 if 语句体验 if 语句进阶 综合应用 01. 开发中的应用场景 生活中的判断几乎是无所不在的,我们每天都在做各种各样的选择,如果这样?如果那样?-- 程序 ...
- p4 学习笔记
新版的p4编译器编译p4-14 p4c test.p4 -o meter --std p4-14 #p4-14和p4-16存在较大差异,参考p4代码时需注意 p4语言特性 无符号数bit类型的操作:此 ...
- Prometheus监控软件部署方法
背景:负责基于区块链的某公正项目的状态上报模块设计编码,基于Prometheus进行二次开发 1.说明Prometheus 是一个开源的服务监控软件,它通过 HTTP 协议从远程机器收集数据并存储在本 ...
- Go语言web开发---Beego的cookie
1.简介 (1)Http是无状态的协议,服务器不能记录浏览器的访问状态,也就是说服务器不能区分两次请求是否是同一个客户端,这样的设计严重阻碍了web程序的设计. (2)Cookie是解决Http协议无 ...
- Python+Selenium - iframe定位
元素在iframe中.在html当中,内嵌了另一个html (iframe) 分辨元素是否在iframe当中 在代码当中,从当前的html切换到iframe当中的html,然后在元素定位 切换方式:d ...