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. 格局决定结局,进化还是毁灭,Prompt在其中扮演什么角色

    GPT 时代, Prompt 的价值你们可能不懂 最近, OpenAI 推出了基于 GPT 模型的 GPTs 以及 Agent Stroe 系统,引发广泛关注.业内讨论热点主要集中在吸引用户体验方面. ...

  2. answer_to_everything

    题解,第一次遇到这种题目纪念一下 攻防世界逆向入门题之answer_to_everything_沐一 · 林的博客-CSDN博客

  3. (Good topic)双指针:判断子序列

    给定字符串 s 和 t ,判断 s 是否为 t 的子序列. 你可以认为 s 和 t 中仅包含英文小写字母.字符串 t 可能会很长(长度 ~= 500,000),而 s 是个短字符串(长度 <=1 ...

  4. 华为ar502H物联网边缘计算网关,在容器内控制/dev/do0开关命令

    执行以下命令进行开关do继电开关,可以听见电位器声音. echo -en  "\x01" > /dev/do0 echo -en  "\x00" > ...

  5. 使用Slurm集群进行分布式图计算:对Github网络影响力的系统分析

    本文分享自华为云社区<基于Slurm集群的分布式图计算应用实践:Github协作网络影响力分析>,作者:yd_263841138 . 1. 引言 Slurm(Simple Linux Ut ...

  6. DataGridView合并单元格,重绘后选中内容被覆盖的解决办法

    DataGridView合并单元格只能进行重绘,网上基本上使用的是下面的方法: 1 /// <summary> 2 /// 说明:纵向合并单元格 3 /// 参数:dgv DataGrid ...

  7. tryhackme进攻性渗透测试-Advanced Exploitation 高级利用

    Steel Mountain 侦察 Nmap -sC -sV -O $IP -oN basic_scan.nmap Nmap -script=vuln $IP -oN vuln_scan.nmap 总 ...

  8. 是谁的简历上全是秒杀商城和RPC啊?

    是不是还在苦于自己简历上的项目离不开商城.RPC.秒杀.论坛.外卖.点评等等烂大街的项目?是不是翻遍全网再很难找到一个既有含金量又能看得懂的项目?那么现在就不用找了,下面这个项目一定适合你! 高性能短 ...

  9. 华企盾DSC导入离线客户端没有获取到信息

    安装客户端的时候禁用了网卡,导致导入离线客户端获取不到信息. 解决方法: 1.启用网卡,重启电脑 2.启用网卡,重装客户端

  10. Android辅助功能

    1:AccessibilityService 新建service public class AccessibilityService extends android.accessibilityserv ...