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 使用的更多相关文章
- Android线程管理之ThreadPoolExecutor自定义线程池
前言: 上篇主要介绍了使用线程池的好处以及ExecutorService接口,然后学习了通过Executors工厂类生成满足不同需求的简单线程池,但是有时候我们需要相对复杂的线程池的时候就需要我们自己 ...
- 并发包的线程池第一篇--ThreadPoolExecutor执行逻辑
学习这个很长时间了一直没有去做个总结,现在大致总结一下并发包的线程池. 首先,任何代码都是解决问题的,线程池解决什么问题? 如果我们不用线程池,每次需要跑一个线程的时候自己new一个,会导致几个问题: ...
- ThreadPoolExecutor源码学习(1)-- 主要思路
ThreadPoolExecutor是JDK自带的并发包对于线程池的实现,从JDK1.5开始,直至我所阅读的1.6与1.7的并发包代码,从代码注释上看,均出自Doug Lea之手,从代码上看JDK1. ...
- ThreadPoolExecutor源码学习(2)-- 在thrift中的应用
thrift作为一个从底到上除去业务逻辑代码,可以生成多种语言客户端以及服务器代码,涵盖了网络,IO,进程,线程管理的框架,着实庞大,不过它层次清晰,4层每层解决不同的问题,可以按需取用,相当方便. ...
- Java 线程 — ThreadPoolExecutor
线程池 线程池处理流程 核心线程池:创建新线程执行任务,需要获取全局锁 队列:将新来的任务加入队列 线程池:大于corePoolSize,并且队列已满,小于maxPoolSize,创建新的worker ...
- java 线程池ThreadPoolExecutor 如何与 AsyncTask() 组合使用。
转载请声明出处谢谢!http://www.cnblogs.com/linguanh/ 这里主要使用Executors中的4种静态创建线程池实例方法中的 newFixedThreadPool()来举例讲 ...
- 【JUC】JDK1.8源码分析之ThreadPoolExecutor(一)
一.前言 JUC这部分还有线程池这一块没有分析,需要抓紧时间分析,下面开始ThreadPoolExecutor,其是线程池的基础,分析完了这个类会简化之后的分析,线程池可以解决两个不同问题:由于减少了 ...
- java线程池ThreadPoolExecutor使用简介
一.简介线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为:ThreadPoolExecutor(int corePoolSize, int m ...
- java线程池ThreadPoolExecutor理解
Java通过Executors提供四种线程池,分别为:newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程.newFixe ...
- 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 ...
随机推荐
- SpringBoot系列之MyBatis Plus自动填充实现
系列博客专栏:SpringBoot2.0系列博客专栏 开发环境 JDK 1.8 SpringBoot2.2.1 Maven 3.2+ Mysql5.7.36 开发工具 IntelliJ IDEA sm ...
- 树莓派4b部署samba服务实现文件共享
注意 samba 生命力很旺盛,软件是在不断更新的, 网上很多针对 samba 网速优化设置截止当前 实测发现有很多已经过期, 甚至有些设置会适得其反,使传输速度更低. 例如, 全网都在配置的参数,& ...
- ReverseMe-120
一道好题,没解出来但是收获很多 贴两位大牛的题解 [精选]攻防世界逆向高手题之ReverseMe-120-CSDN博客 攻防世界ReverseMe-120详解_攻防世界reverseme基本思路-CS ...
- 解密Spring Cloud微服务调用:如何轻松获取请求目标方的IP和端口
公众号「架构成长指南」,专注于生产实践.云原生.分布式系统.大数据技术分享. 目的 Spring Cloud 线上微服务实例都是2个起步,如果出问题后,在没有ELK等日志分析平台,如何确定调用到了目标 ...
- 一文带你掌握C语言的分支结构
C语言分支结构详解 1. if 语句 在本篇博客文章中,我们将深入探讨C语言中的if语句及其相关用法.if语句是一种用于条件判断的分支语句,它允许我们根据条件的真假来执行不同的代码块. 1.1 if ...
- git推送时报错:fatal: unable to access 'https://github.com/xxx/xxx.git/': Failed to connect to 127.0.0.1 port 31181 after 2063 ms: Connection refused
一.报错原因 1.因为git在拉取或者提交项目时,中间会有git的http和https代理,但是我们本地环境本身就有SSL协议了,所以取消git的https代理即可,不行再取消http的代理. 2.当 ...
- GOF23--23种设计模式(一)
一.什么是设计模式 设计模式(Design Pattern)是前辈们对代码开发经验的总结,是解决一系列特定问题的套路. 它不是语法规定,而是一套用来提高代码复用性,可读性,可维护性,稳健性,安全性的 ...
- [ARC137E] Baker
Problem Statement Snuke runs a bakery. He is planning for the next $N$ days. Let us call these days ...
- int和String的相互转换
- DEDECMS 后台系统用户授权目录更改为无限级(默认为二级授权)
在做一个学校的项目,分类有四级分类,总共一百多个分类,因为每个分类对应不同的老师,用于上传资料作为考核,但是添加系统用户的时候发现DEDECMS只有两级分类,所以修改啦一些代码,目前不知道是否修改完全 ...