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语言中strchr()和index()

    一. C标准的一些问题 在ubuntu下rindex()函数使用没有问题,在minGW下会报错,undefined reference to `rindex',warning: implicit de ...

  2. L2-040 哲哲打游戏

    这题读懂题目之后就发现它很呆 #include <bits/stdc++.h> using namespace std; const int N = 100010, M = 110; ve ...

  3. 2020年第十一届蓝桥杯第二场C/C++ B组省赛题解

    2020年第十一届蓝桥杯C/C++ B组省赛题解 试题A:门牌制作 [问题描述] 小蓝要为一条街的住户制作门牌号. 这条街一共有 \(2020\) 位住户,门牌号从 \(1\) 到 \(2020\) ...

  4. 震荡指标(一)RSI指标

    相对强弱指数RSI是根据一定时期内上涨点数和涨跌点数之和的比率制作出的一种技术曲线.能够反映出市场在一定时期内的景气程度.由威尔斯.威尔德(Welles Wilder)最早应用于期货买卖,后来人们发现 ...

  5. 【开源项目推荐】-支持GPT的智能数据库客户端与报表工具——Chat2DB

    2023年是人工智能爆火的一年,ChatGPT为首的一系列的大模型的出现,让生成式人工智能彻底火了一把.但有人会说,GPT对于我们数据开发来说并没有什么作用啊? 今天为大家推荐的开源项目,就是GPT在 ...

  6. [ABC233G] Strongest Takahashi

    Problem Statement There is a $N \times N$ grid, with blocks on some squares. The grid is described b ...

  7. Shell下处理JSON数据工具向导

    目录 下载离线安装包 安装 源码包安装 选项及含义 JQ 程序代码演示在线平台 JQ 语法 基本过滤器 身份运算符 --- . 标识符-索引 --- .foo`, `.foo.bar 对象索引 --- ...

  8. NLP复习之向量语义

    向量语义 词汇语义 语义概念(sense or concept)是单词含义(word sense)的组成部分,词原型可以是多义的. 同义词是指:在某些或者全部的上下文中,单词之间有相同或近似含义 可能 ...

  9. 聊聊流式数据湖Paimon(四)

    Partial Update 数据打宽 通过不同的流写不同的字段,打宽了数据的维度,填充了数据内容:如下所示: --FlinkSQL参数设置 set `table.dynamic-table-opti ...

  10. --{module_name}_binary_host_mirror和--{module_name}_binary_site

    --{module_name}_binary_host_mirror和--{module_name}_binary_site demo // .npmrc文件 sass_binary_site=htt ...