ThreadPoolExecutor 介绍

简写:

package com.vipsoft.Thread;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger; public class ThreadPoolExecutorTest { public static void main(String[] args) throws Exception {
ThreadPoolExecutor executor = new ThreadPoolExecutor(
2,
4,
10L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(2),
new ThreadFactory() {
private final AtomicInteger mThreadNum = new AtomicInteger(1); @Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r, "Thread-" + mThreadNum.getAndIncrement());
System.out.println(t.getName() + " has been created");
return t;
}
},
new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
// 可做日志记录等
System.err.println(r.toString() + " rejected " + executor.getTaskCount());
}
}); executor.prestartAllCoreThreads(); // 预启动所有核心线程 for (int i = 1; i <= 10; i++) {
final String taskName = String.valueOf(i);
executor.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println(this.toString() + " is running!");
Thread.sleep(3000); //让任务执行慢点
} catch (InterruptedException e) {
e.printStackTrace();
}
} @Override
public String toString() {
return "MyTask [name=" + taskName + "]";
}
});
} //可读性好些
// Runnable call = new Runnable() {
// @Override
// public void run() {
// try {
// System.out.println(this.toString() + " is running!");
// Thread.sleep(3000); //让任务执行慢点
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// } // @Override
// public String toString() {
// return "MyTask [name=" + taskName + "]";
// }
// } // for (int i = 1; i <= 10; i++) {
// final String taskName = String.valueOf(i);
// executor.execute(call);
// } System.in.read(); //阻塞主线程
} }

常规写法:

package com.vipsoft.Thread;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger; public class ThreadPoolExecutorTest { public static void main(String[] args) throws Exception {
int corePoolSize = 2;
int maximumPoolSize = 5;
long keepAliveTime = 10;
TimeUnit unit = TimeUnit.SECONDS;
BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(3); //定义一个大小为2的队列,只等有一个任务在排队等,多出来的需要开新线程
ThreadFactory threadFactory = new MyTreadFactory();
RejectedExecutionHandler handler = new MyPolicy();
ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
System.out.println("预启动线程(备战)");
executor.prestartAllCoreThreads(); // 预启动所有核心线程,处于备战
System.out.println("预启动线程数(备战):" + executor.getPoolSize());
for (int i = 1; i <= 10; i++) {
System.out.println(System.currentTimeMillis() + " " + "开始 下发任务:" + i + " 当前线程总数:" + executor.getPoolSize());
MyTask task = new MyTask(String.valueOf(i));
executor.execute(task);
System.out.println(System.currentTimeMillis() + " " + "完成 下发任务:" + i + " 当前线程总数:" + executor.getPoolSize() + " 队列中的线程数量:" + workQueue.size());
Thread.sleep(1); //停1毫秒,日志记录,时间后方便分析
if (i == 9) {
//TODO Thread.sleep(3000); //任务9下发后【会被拒绝】,停3秒,等队列或线程释放后,再下发任务10,这时候任务10不会被拒绝
}
}
System.in.read(); //阻塞主线程
} static class MyTreadFactory implements ThreadFactory { private final AtomicInteger mThreadNum = new AtomicInteger(1); @Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r, "Thread-" + mThreadNum.getAndIncrement());
System.out.println(System.currentTimeMillis() + " " + t.getName() + " has been created");
return t;
}
} public static class MyPolicy implements RejectedExecutionHandler { public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
// 可做日志记录等
System.err.println(System.currentTimeMillis() + " " + r.toString() + " rejected from " + e.toString());
}
} static class MyTask implements Runnable {
private String name; public MyTask(String name) {
this.name = name;
} @Override
public void run() {
try {
System.out.println(System.currentTimeMillis() + " " + this.toString() + " 开始运行! " + Thread.currentThread().getName());
Thread.sleep(3000); //让任务执行慢点
System.out.println(System.currentTimeMillis() + " " + this.toString() + " 运行结束! " + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
} @Override
public String toString() {
return "MyTask [name=" + this.name + "]";
}
}
}

运行结果:忽略图片内容

将日志按时间排序后解读:可容纳任务数 = 最大线程数 + 最大队列数

预启动线程(备战)
预启动线程数(备战):2
1654760985275 Thread-1 has been created //预启动创建线程
1654760985275 Thread-2 has been created //预启动创建线程
1654760985275 开始 下发任务:1 当前线程总数:2 //下发任务,当前有2线程(预启动创建)
1654760985276 MyTask [name=1] 开始运行! Thread-2
1654760985276 完成 下发任务:1 当前线程总数:2 //下发任务,当前有2线程(预启动创建)
1654760985278 MyTask [name=2] 开始运行! Thread-1
1654760985278 开始 下发任务:2 当前线程总数:2
1654760985278 完成 下发任务:2 当前线程总数:2 //下发任务,当前有2线程(预启动创建)
1654760985280 开始 下发任务:3 当前线程总数:2
1654760985280 完成 下发任务:3 当前线程总数:2 //下发任务,当前有2线程(预启动创建)
1654760985282 开始 下发任务:4 当前线程总数:2
1654760985282 完成 下发任务:4 当前线程总数:2 //下发任务,当前有2线程(预启动创建)
1654760985284 开始 下发任务:5 当前线程总数:2
1654760985284 完成 下发任务:5 当前线程总数:2 //下发任务,当前有2线程(预启动创建)
1654760985286 MyTask [name=6] 开始运行! Thread-3
1654760985286 Thread-3 has been created
1654760985286 开始 下发任务:6 当前线程总数:2
1654760985286 完成 下发任务:6 当前线程总数:3 //下发任务,当前有2线程,3个队列,第6个任务,已经不够放了,新建一个线程
1654760985288 MyTask [name=7] 开始运行! Thread-4
1654760985288 Thread-4 has been created
1654760985288 开始 下发任务:7 当前线程总数:3
1654760985288 完成 下发任务:7 当前线程总数:4 //下发任务,当前有3线程,3个队列,第8个任务,已经不够放了,新建一个线程
1654760985290 MyTask [name=8] 开始运行! Thread-5
1654760985290 Thread-5 has been created
1654760985290 开始 下发任务:8 当前线程总数:4
1654760985290 完成 下发任务:8 当前线程总数:5 //下发任务,当前有4线程,3个队列,第8个任务,已经不够放了,新建一个线程
1654760985292 MyTask [name=9] rejected from java.util.concurrent.ThreadPoolExecutor@4b1210ee[Running, pool size = 5, active threads = 5, queued tasks = 3, completed tasks = 0]
1654760985292 开始 下发任务:9 当前线程总数:5
1654760985292 完成 下发任务:9 当前线程总数:5 //下发任务,当前有5线程,3个队列,第9个任务,已经不够放了,新建一个线程(超过了最大线程数 maximumPoolSize + 队列数 workQueue )拒绝任务9
1654760985294 MyTask [name=10] rejected from java.util.concurrent.ThreadPoolExecutor@4b1210ee[Running, pool size = 5, active threads = 5, queued tasks = 3, completed tasks = 0]
1654760985294 开始 下发任务:10 当前线程总数:5
1654760985294 完成 下发任务:10 当前线程总数:5 //下发任务,当前有5线程,3个队列,第10个任务,已经不够放了,新建一个线程(超过了最大线程数+队列数)拒绝任务10
1654760988276 MyTask [name=1] 运行结束! Thread-2 //等有任务结束后,再去下发任务9、10,就不会抛弃任务了
1654760988276 MyTask [name=3] 开始运行! Thread-2
1654760988278 MyTask [name=2] 运行结束! Thread-1
1654760988278 MyTask [name=4] 开始运行! Thread-1
1654760988286 MyTask [name=5] 开始运行! Thread-3
1654760988286 MyTask [name=6] 运行结束! Thread-3
1654760988288 MyTask [name=7] 运行结束! Thread-4
1654760988291 MyTask [name=8] 运行结束! Thread-5
1654760991288 MyTask [name=3] 运行结束! Thread-2
1654760991288 MyTask [name=4] 运行结束! Thread-1
1654760991288 MyTask [name=5] 运行结束! Thread-3

ThreadPoolExecutor 使用的更多相关文章

  1. Android线程管理之ThreadPoolExecutor自定义线程池

    前言: 上篇主要介绍了使用线程池的好处以及ExecutorService接口,然后学习了通过Executors工厂类生成满足不同需求的简单线程池,但是有时候我们需要相对复杂的线程池的时候就需要我们自己 ...

  2. 并发包的线程池第一篇--ThreadPoolExecutor执行逻辑

    学习这个很长时间了一直没有去做个总结,现在大致总结一下并发包的线程池. 首先,任何代码都是解决问题的,线程池解决什么问题? 如果我们不用线程池,每次需要跑一个线程的时候自己new一个,会导致几个问题: ...

  3. ThreadPoolExecutor源码学习(1)-- 主要思路

    ThreadPoolExecutor是JDK自带的并发包对于线程池的实现,从JDK1.5开始,直至我所阅读的1.6与1.7的并发包代码,从代码注释上看,均出自Doug Lea之手,从代码上看JDK1. ...

  4. ThreadPoolExecutor源码学习(2)-- 在thrift中的应用

    thrift作为一个从底到上除去业务逻辑代码,可以生成多种语言客户端以及服务器代码,涵盖了网络,IO,进程,线程管理的框架,着实庞大,不过它层次清晰,4层每层解决不同的问题,可以按需取用,相当方便. ...

  5. Java 线程 — ThreadPoolExecutor

    线程池 线程池处理流程 核心线程池:创建新线程执行任务,需要获取全局锁 队列:将新来的任务加入队列 线程池:大于corePoolSize,并且队列已满,小于maxPoolSize,创建新的worker ...

  6. java 线程池ThreadPoolExecutor 如何与 AsyncTask() 组合使用。

    转载请声明出处谢谢!http://www.cnblogs.com/linguanh/ 这里主要使用Executors中的4种静态创建线程池实例方法中的 newFixedThreadPool()来举例讲 ...

  7. 【JUC】JDK1.8源码分析之ThreadPoolExecutor(一)

    一.前言 JUC这部分还有线程池这一块没有分析,需要抓紧时间分析,下面开始ThreadPoolExecutor,其是线程池的基础,分析完了这个类会简化之后的分析,线程池可以解决两个不同问题:由于减少了 ...

  8. java线程池ThreadPoolExecutor使用简介

    一.简介线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为:ThreadPoolExecutor(int corePoolSize, int m ...

  9. java线程池ThreadPoolExecutor理解

    Java通过Executors提供四种线程池,分别为:newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程.newFixe ...

  10. java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@1f303192 rejected from java.util.concurrent.ThreadPoolExecutor@11f7cc04[Terminated, pool size = 0, active threads

    java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@1f303192 rejec ...

随机推荐

  1. C/C++ extern “C“ 的问题

    声明 文章中的部分代码引用来在: https://blog.csdn.net/u012234115/article/details/43272441 场景 今天在CSDN中看到了一篇关于 extern ...

  2. 题解 CF1739B

    题目大意: 有一个非负整数序列 \(A\),定义序列 \(D\) 是序列 \(A\) 的绝对值差分序列,问给定序列 \(D\),能否求出唯一的序列 \(A\),若不能,输出 \(-1\),否则输出序列 ...

  3. 一个简单案例的Vue2.0源码

    本文学习vue2.0源码,主要从new Vue()时发生了什么和页面的响应式更新2个维度了解Vue.js的原理.以一个简单的vue代码为例,介绍了这个代码编译运行的流程,在流程中原始DOM的信息会被解 ...

  4. python循环之for循环

    当我们想让列表中的元素一个一个打印出时,用多个print()就显得代码很繁琐了,这是我们就可以用到循环 list_1 = ['one', 'two', 'three', 'four', 'five'] ...

  5. 工厂模式(Factory Method)

    模式定义 定义一个用于创建对象的接口,让子类决定实例化哪一个类.Factory Method使得一个类的实例化延迟(目的:解耦)到子类. 要点总结 Factory Method模式用于隔离类对象的使用 ...

  6. springBoot + 工厂模式 实现 快递鸟、顺丰和快递100的物流查询

    前言: 在Spring Boot中实现快递鸟.顺丰和快递100的物流查询功能通常需要与它们提供的API进行交互.当然使用他们的API 我们是需要申请和注册,从而去拿到 key 来进行调用.所以为注册的 ...

  7. Linux RN6752 驱动编写

    一.概述 关于 RN6752V1 这个芯片这里就不做介绍了,看到这篇笔记的小伙伴应该都明白,虽然说 RN6752V1 芯片是 AHD 信号的解码芯片,但是也可以把芯片当做是一个 YUV 信号的 MIP ...

  8. 2023-12-02:用go语言,如何求模立方根? x^3=a mod p, p是大于等于3的大质数, a是1到p-1范围的整数常数, x也是1到p-1范围的整数,求x。 p过大,x不能从1到p-1遍

    2023-12-02:用go语言,如何求模立方根? x^3=a mod p, p是大于等于3的大质数, a是1到p-1范围的整数常数, x也是1到p-1范围的整数,求x. p过大,x不能从1到p-1遍 ...

  9. C++学习笔记九:值,常量,常表达式和常初始化

    1. 值: Literal: Data that is directly represented in code without going through some other variable s ...

  10. hdu4365 Palindrome graph

    Palindrome graph Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...