*/
public class ThreadDemo22 {
public static void main(String[] args) {
//创建单个可以延迟任务的线程池
ScheduledExecutorService threadpool = Executors.newSingleThreadScheduledExecutor();
System.out.println("添加任务的时间:"+new Date());
threadpool.schedule(()->{
System.out.println("执行任务的时间:"+new Date());
},5,TimeUnit.SECONDS);
}
}
执行结果
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210324151933713.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3draDE4ODkxODQzMTY1,size_16,color_FFFFFF,t_70)
* * *
方式五:创建多个可以执行延迟任务的线程池
代码案例
/**
-
创建可以执行多个延迟任务的线程池
-
注意返回值以及调用方法
*/
public class ThreadDemo23 {
public static void main(String[] args) {
ScheduledExecutorService threadpool = Executors.newScheduledThreadPool(5);
for (int i = 0; i < 6; i++) {
System.out.println("添加任务的时间"+new Date());
threadpool.schedule(()->{
System.out.println("执行任务的时间"+new Date());
},5,TimeUnit.SECONDS);
}
}
}
执行结果
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210324153556795.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3draDE4ODkxODQzMTY1,size_16,color_FFFFFF,t_70)
方式六:创建一个抢占式执行的线程池,执行任务的顺序不确定
代码案例
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
-
创建一个抢占式执行的线程池
-
执行任务的顺序不确定
*/
public class ThreadDemo24 {
public static void main(String[] args) {
//创建线程池
ExecutorService threadpool = Executors.newWorkStealingPool();
for (int i = 0; i < 5; i++) {
int index = i;
threadpool.submit(()->{
System.out.println("任务 "+index+" 正在被线程名称为 "+Thread.currentThread().getName()+"执行");
});
}
//确保任务执行完成
while (!threadpool.isTerminated()) {
}
}
}
执行结果
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210324154649590.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3draDE4ODkxODQzMTY1,size_16,color_FFFFFF,t_70)
方式七:是最原始的一种,也是最重要的一种,使用ThreadPoolExcutors创建线程池,里面至少传五个参数
7.1参数的介绍
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210324161453459.png)
1.corPoolSize 核心线程数,线程池中始终存活的线程数
2.mamaximumPoolSize 线程池所能容纳的最大线程数,当线程池的任务队列满了之后可以创建的最大线程数
3.keepAliveTime 最大线程数可以存活的时间,如果超过该时长,非核心线程就会被回收,也就是当线程中没有任务执行时,最大线程就会销毁一部分,最终保持核心线程数量的线程。
4.指定keepAliveTime参数的时间单位。常用的有:TimeUnit.MILLISECONDS(毫秒)、TimeUnit.SECONDS(秒)、TimeUnit.MINUTES(分)
5.一个阻塞队列,用来存储线程池等待执行的任务,均为线程安全
6.threadFactory:线程工厂。用于指定为线程池创建新线程的方式。
7.handler: 拒绝处理任务时的策略——拒绝策略有五种,如:
* AbortPolicy:拒绝并抛出异常。
* CallerRunsPolicy:使用当前调用的线程来执行此任务。
* DiscardOldestPolicy:抛弃队列头部(最旧)的一个任务,并执行当前任务。
* DiscardPolicy:忽略并抛弃当前任务。
* 程序员自己定义的拒绝策略
ThreadPoolExecutors的执行执行逻辑
1.当任务量较少的时候使用线程池提供的核心线程数执行执行
2.当任务超过核心线程数的时候,新来的任务就会存储到队列
3.当队列已经存储满的了,那么就会增加线程的数量,一直增加到可以扩展的最大线程数,也就是mamaximumPoolSize
4.当最大线程数已满,任务队列已满,就会执行线程池的拒绝策略(5钟拒绝策略)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210324173830500.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3draDE4ODkxODQzMTY1,size_16,color_FFFFFF,t_70)
**注意**
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210324162329170.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3draDE4ODkxODQzMTY1,size_16,color_FFFFFF,t_70)
[]( )拒绝策略(ThreadPoolExecutors)
-------------------------------------------------------------------------------------------
JDK(4钟拒绝策略)
* 拒绝执行新来任务,并抛出异常(默认拒绝策略)
* 可以使用主线程来执行新任务(main主线程)
* 忽略当前任务,但不报错
* 忽略旧的任务,也不报错
程序员自己定义的拒绝策略
```
拒绝策略一 :拒绝执行新来任务,并抛出异常
```
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadDemo25 {
public static void main(String[] args) {
//最大线程数一定要大于等于核心线程数,不然就会报错
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 5, 100, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(2), new ThreadPoolExecutor.AbortPolicy());
for (int i = 0; i < 10; i++) {
final int index = i;
threadPoolExecutor.submit(() -> {
System.out.println("我是任务 "+ index);
});
}
}
}
执行结果
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210324164945891.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3draDE4ODkxODQzMTY1,size_16,color_FFFFFF,t_70)
* * *
拒绝策略二:可以使用主线程来执行新任务(main主线程)
代码案例
/**
- 拒绝策略二:可以使用主线程来执行新任务(main主线程)
*/
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadDemo26 {
public static void main(String[] args) {
//最大线程数一定要大于等于核心线程数,不然就会报错
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 5, 100, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(2), new ThreadPoolExecutor.CallerRunsPolicy());
for (int i = 0; i < 10; i++) {
final int index = i;
threadPoolExecutor.submit(() -> {
System.out.println("我是任务 "+ index+"线程名称:"+Thread.currentThread().getName());
});
}
}
}
执行结果
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210324165858419.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3draDE4ODkxODQzMTY1,size_16,color_FFFFFF,t_70)
* * *
拒绝策略三:忽略当前任务,但不报错
代码案例
**
- 拒绝策略三:忽略当前任务,但是不报错
*/
public class ThreadDemo27 {
public static void main(String[] args) {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 5, 100, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(2), new ThreadPoolExecutor.DiscardPolicy());
for (int i = 0; i < 10; i++) {
final int index = i;
threadPoolExecutor.submit(() -> {
System.out.println("我是任务 "+ index+"线程名称:"+Thread.currentThread().getName());
});
}
}
}
执行结果
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210324170517825.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3draDE4ODkxODQzMTY1,size_16,color_FFFFFF,t_70)
* * *
拒绝策略四:忽略旧任务
代码案例
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadDemo28 {
public static void main(String[] args) {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 5, 100, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(2), new ThreadPoolExecutor.DiscardOldestPolicy());
for (int i = 0; i < 10; i++) {
final int index = i;
threadPoolExecutor.submit(() -> {
System.out.println("我是任务 "+ index+"线程名称:"+Thread.currentThread().getName());
});
}
}
}
执行结果
![在这里插入图片描述](https://img-blog.csdnimg.cn/2021032417160954.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3draDE4ODkxODQzMTY1,size_16,color_FFFFFF,t_70)
* * *
拒绝策略五:自定义拒绝策略
代码案例