自定义线程池

1.若Executors工厂类无法满足需求,可以自己使用工厂类创建线程池,底层都是使用了ThreadPoolExecutor这个类可以自定义。

  1. public ThreadPoolExecutor(int corePoolSize(当前核心线程数),
  2. int maximunPoolSize(最大线程数),
  3. long keepAliveTime(保持活跃时间),
  4. TimeUnit utin(时间单位),
  5. BlockingQueue<Runnable> workQueue(线程队列容器),
  6. ThreadFactory threadFactory(线程工厂),
  7. RejectedExecutionHandler rejectedExecutionHandler(拒绝执行的方法,线程队列阻塞到容器等待、例:限制最大执行、));
    2.有界队列【ArrayBlockingQueue】,若有新的任务则立即去执行:若有新的线程需要执行,目标线程池实际数小于"coreRoolSize",则优先参加线程,若大于,

则会将任务加入队 列中,若队列已经满,则在总线程数不大于maximumPoolSize(最大coreRoolSize数)的前提下。创建一个新的线程,若大于               maximumPoolSize则实行拒绝策略、或其他处理方式。

    3.无界队列【LinkedBlockingQueue】与有界队列对比:除非资源耗尽,否则无界队列在加入任务不存在失败的情况下,当有新的任务到来,系统的线程数小于
       corePoolSize的时候,则新建线程去执行任务队列,,达到maxCorePoolsize后就不会增加了,若后续还有任务到来,而且没有空闲的资源,则把任务进行
        队列中去等待。若创建任务与处理任务的速度差异很大,无界队列保持快速增加等待的任务空间,一直到资源耗尽。
    4.拒绝策略
                    Abortlicy:直接抛出异常、核心系统则不会受到影响。
                    CallerRunspPolicy:该策略直接在调用者现场,运行当前被拒绝的任务、丢弃的任务(我刚刚进行队列就满了,那么就让我插个队执行)。
                    DiscardOldestPolicy:丢弃最老的一个请求(被阻塞在队列中很长时间),尝试直接运行当前被拒绝的任务。
                    DiscardPolicy:丢弃无法处理的任务,被给与任何的后续处理。
    5.自定义策略
                    
  1. implements RejectedExecutionHandle
案例1:有界队列
  1. package demo8.threadPool;
  2. import java.util.concurrent.*;
  3. public class CustomThreadPool1 {
  4. /* 有界队列ArrayBlockingQueue:
  5. 若有新的线程需要执行,日光线程池实际数小于"coreRoolSize",则优先参加线程,若大于,则会将任务加入队列中,若队列已经满,则在总线程
  6. 数不大于maximumPoolSize(最大coreRoolSize数)的前提下。创建一个新的线程,若大于maximumPoolSize则实行拒绝策略、或其他处理方式。*/
  7. public static void main(String[] args) {
  8. BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<Runnable>(3);
  9. ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1,
  10. 2,
  11. 60,
  12. TimeUnit.SECONDS,
  13. blockingQueue);
  14. UserTask userTask1 = new UserTask(1, "任务-1");
  15. UserTask userTask2 = new UserTask(2, "任务-2");
  16. UserTask userTask3 = new UserTask(3, "任务-3");
  17. UserTask userTask4 = new UserTask(4, "任务-4");
  18. UserTask userTask5 = new UserTask(5, "任务-5");
  19. threadPoolExecutor.execute(userTask1);
  20. threadPoolExecutor.execute(userTask2);
  21. threadPoolExecutor.execute(userTask3);
  22. threadPoolExecutor.execute(userTask4);
  23. threadPoolExecutor.execute(userTask5);
  24. try {
  25. Thread.sleep(1000);
  26. } catch (InterruptedException e) {
  27. e.printStackTrace();
  28. }
  29. threadPoolExecutor.shutdown();
  30. }
  31. }
  32. 输出:
  33. pool-1-thread-1 run taskId:1
    pool-1-thread-2 run taskId:5
    pool-1-thread-2 run taskId:3
    pool-1-thread-1 run taskId:2
    pool-1-thread-2 run taskId:4
        这种情况处理完所有的任务
  1. package demo8.threadPool;
  2. /**
  3. * Created by liudan on 2017/7/23.
  4. */
  5. public class UserTask implements Runnable {
  6. private int id;
  7. private String taskName;
  8. @Override
  9. public void run() {
  10. try {
  11. Thread.sleep(1000);
  12. System.err.println(Thread.currentThread().getName()+"\t run taskId:"+this.getId());
  13. } catch (InterruptedException e) {
  14. e.printStackTrace();
  15. }
  16. }
  17. public UserTask() {
  18. }
  19. public UserTask(int id, String taskName) {
  20. this.id = id;
  21. this.taskName = taskName;
  22. }
  23. public int getId() {
  24. return id;
  25. }
  26. public void setId(int id) {
  27. this.id = id;
  28. }
  29. public String getTaskName() {
  30. return taskName;
  31. }
  32. public void setTaskName(String taskName) {
  33. this.taskName = taskName;
  34. }
  35. @Override
  36. public String toString() {
  37. return "UserTask{" +
  38. "id=" + id +
  39. '}';
  40. }
  41. }

案例2:拒绝任务,超出暂缓任务对了大小

  1. public static void main(String[] args) {
  2. BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<Runnable>(3);
  3. ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1,
  4. 2,
  5. 60,
  6. TimeUnit.SECONDS,
  7. blockingQueue);
  8. UserTask userTask1 = new UserTask(1, "任务-1");
  9. UserTask userTask2 = new UserTask(2, "任务-2");
  10. UserTask userTask3 = new UserTask(3, "任务-3");
  11. UserTask userTask4 = new UserTask(4, "任务-4");
  12. UserTask userTask5 = new UserTask(5, "任务-5");
  13. UserTask userTask6 = new UserTask(6, "任务-6");多加一个
  14. threadPoolExecutor.execute(userTask1);
  15. threadPoolExecutor.execute(userTask2);
  16. threadPoolExecutor.execute(userTask3);
  17. threadPoolExecutor.execute(userTask4);
  18. threadPoolExecutor.execute(userTask5);
  19. threadPoolExecutor.execute(userTask6);
  20. try {
  21. Thread.sleep(1000);
  22. } catch (InterruptedException e) {
  23. e.printStackTrace();
  24. }
  25. threadPoolExecutor.shutdown();
  26. }
  27. 输出:
  28. Exception in thread "main" java.util.concurrent.RejectedExecutionException:
  29. Task UserTask{id=6} rejected from java.util.concurrent.ThreadPoolExecutor@6f94fa3e
  30. [Running, pool size = 2, active threads = 2, queued tasks = 3, completed tasks = 0]
    at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2047)
    at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823)
    at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1369)
    at demo8.threadPool.CustomThreadPool1.main(CustomThreadPool1.java:35)
    pool-1-thread-1 run taskId:1
    pool-1-thread-2 run taskId:5
    pool-1-thread-1 run taskId:2
    pool-1-thread-2 run taskId:3
    pool-1-thread-1 run taskId:4
案例3:自定义拒绝策略
  1. package demo8.threadPool;
  2. import java.util.concurrent.RejectedExecutionHandler;
  3. import java.util.concurrent.ThreadPoolExecutor;
  4. public class CustomDiscardPolicy implements RejectedExecutionHandler {
  5. public CustomDiscardPolicy() {
  6. }
  7. @Override
  8. public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
  9. System.err.println("拒绝任务");
  10. /**
  11. * 用日志记录保存下,可做后续的扩展操作
  12. */
  13. System.err.println("加入任务log...\t"+r.toString());
  14. }
  15. }
  1. public static void main(String[] args) {
  2. BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<Runnable>(3);
  3. ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1,
  4. 2,
  5. 60,
  6. TimeUnit.SECONDS,
  7. blockingQueue,
  8. new CustomDiscardPolicy());//使用自定义拒绝策略
  9. UserTask userTask1 = new UserTask(1, "任务-1");
  10. UserTask userTask2 = new UserTask(2, "任务-2");
  11. UserTask userTask3 = new UserTask(3, "任务-3");
  12. UserTask userTask4 = new UserTask(4, "任务-4");
  13. UserTask userTask5 = new UserTask(5, "任务-5");
  14. UserTask userTask6 = new UserTask(6, "任务-6");
  15. threadPoolExecutor.execute(userTask1);
  16. threadPoolExecutor.execute(userTask2);
  17. threadPoolExecutor.execute(userTask3);
  18. threadPoolExecutor.execute(userTask4);
  19. threadPoolExecutor.execute(userTask5);
  20. threadPoolExecutor.execute(userTask6);
  21. try {
  22. Thread.sleep(1000);
  23. } catch (InterruptedException e) {
  24. e.printStackTrace();
  25. }
  26. threadPoolExecutor.shutdown();
  27. }
  28. 输出:
  29. 拒绝任务
    加入任务log... UserTask{id=6}
    pool-1-thread-1 run taskId:1
    pool-1-thread-2 run taskId:5
    pool-1-thread-1 run taskId:2
    pool-1-thread-2 run taskId:3
    pool-1-thread-1 run taskId:4
案例4:无界队列LinkedBlockingQueue
  1. package demo8.threadPool;
  2. import java.util.concurrent.*;
  3. public class CustomThreadPool2 {
  4. /* 无界队列LinkedBlockingQueue:
  5. 与有界队列相比,除非系统资源耗尽,否则无界的任务队列不存在加入任务队列失败的情况下,当有新的任务到来,系统的线程数小于coreRoolSize
  6. 时候,则新建线程执行任务,当到达coreRoolSize后就不会增加了,若后续还有新的任务加入,而且没有空闲的线程资源,则任务直接进入队列等待
  7. 。若任务创建和处理速度差异很大,无界队列保持快速增长,知道耗尽系统内存。*/
  8. public static void main(String[] args) throws InterruptedException {
  9. BlockingQueue<Runnable> blockingQueue = new LinkedBlockingQueue<Runnable>();
  10. ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5,10,120L, TimeUnit.SECONDS,blockingQueue);
  11. //ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool(4);
  12. for (int i=1;i<=20;i++){
  13. threadPoolExecutor.execute(new UserTask(i,"任务-"+i));
  14. }
  15. Thread.sleep(1000);
  16. System.err.println("blockingQueue size:"+blockingQueue.size());
  17. Thread.sleep(2000);
  18. }
  19. }
  20. 输出:
  21. pool-1-thread-1 run taskId:1
    pool-1-thread-2 run taskId:2
    pool-1-thread-3 run taskId:3
    pool-1-thread-4 run taskId:4
    pool-1-thread-5 run taskId:5
    blockingQueue size:10
    pool-1-thread-2 run taskId:7
    pool-1-thread-4 run taskId:9
    pool-1-thread-3 run taskId:8
    pool-1-thread-1 run taskId:6
    pool-1-thread-5 run taskId:10
    pool-1-thread-2 run taskId:11
    pool-1-thread-1 run taskId:14
    pool-1-thread-3 run taskId:13
    pool-1-thread-4 run taskId:12
    pool-1-thread-5 run taskId:15
    pool-1-thread-1 run taskId:17
    pool-1-thread-4 run taskId:19
    pool-1-thread-5 run taskId:20
    pool-1-thread-2 run taskId:16
    pool-1-thread-3 run taskId:18

20.custom自定义线程池的更多相关文章

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

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

  2. 一个自定义线程池的小Demo

    在项目中如果是web请求时候,IIS会自动分配一个线程来进行处理,如果很多个应用程序共享公用一个IIS的时候,线程分配可能会出现一个问题(当然也是我的需求造成的) 之前在做项目的时候,有一个需求,就是 ...

  3. C#自定义线程池

    自定义线程池-c#的简单实现 下面是代码,希望大家提出更好的建议: 1.ThreadManager.cs using System; using System.Threading; using Sys ...

  4. SOFA 源码分析 — 自定义线程池原理

    前言 在 SOFA-RPC 的官方介绍里,介绍了自定义线程池,可以为指定服务设置一个独立的业务线程池,和 SOFARPC 自身的业务线程池是隔离的.多个服务可以共用一个独立的线程池. API使用方式如 ...

  5. Spring Boot使用@Async实现异步调用:自定义线程池

    前面的章节中,我们介绍了使用@Async注解来实现异步调用,但是,对于这些异步执行的控制是我们保障自身应用健康的基本技能.本文我们就来学习一下,如果通过自定义线程池的方式来控制异步调用的并发. 定义线 ...

  6. SpringBoot 自定义线程池

    本教程目录: 自定义线程池 配置spring默认的线程池 1. 自定义线程池 1.1 修改application.properties task.pool.corePoolSize=20 task.p ...

  7. SpringBoot 自定义线程池,多线程

    原文:https://www.jianshu.com/p/832f2b162450 我们都知道spring只是为我们简单的处理线程池,每次用到线程总会new 一个新的线程,效率不高,所以我们需要自定义 ...

  8. Android AsyncTask 深度理解、简单封装、任务队列分析、自定义线程池

    前言:由于最近在做SDK的功能,需要设计线程池.看了很多资料不知道从何开始着手,突然发现了AsyncTask有对线程池的封装,so,就拿它开刀,本文将从AsyncTask的基本用法,到简单的封装,再到 ...

  9. Android 自定义线程池的实战

    前言:在上一篇文章中我们讲到了AsyncTask的基本使用.AsyncTask的封装.AsyncTask 的串行/并行线程队列.自定义线程池.线程池的快速创建方式. 对线程池不了解的同学可以先看 An ...

随机推荐

  1. Zookeeper(二)Zookeeper原理与API应用

    一 Zookeeper概述 1.1 概述 Zookeeper是Google的Chubby一个开源的实现.它是一个针对大型分布式系统的可靠协调系统,提供的功能包括:配置维护.名字服务. 分布式同步.组服 ...

  2. Eclipse中用两个控制台测试网络通信程序

    1.启动发送端和接收端程序,这时在控制台可以看到两个程序在运行,如下图. 2.这种情况下只有一个控制台窗口,不便于测试程序,于是新建一个控制台窗口,如下图. 3.这时可以发现已经有了两个控制台窗口了, ...

  3. Robot Framework + Selenium2Lib

    Robot Framework + Selenium2Lib 最近一段时间,公司在推行自动化测试流程,本人有幸参与了自定义通用控件的关键字封装和脚本辅助编写.数据驱动管理.测试用例执行管理等一系列工具 ...

  4. Wannafly挑战赛18 C - 异或和

    思路:我刚开始是想旋转四次坐标,每次用bit计算每个点左上角的点到这个点的距离,TLE了.... 这种算曼哈顿距离的可以将x 轴和 y 轴独立开来,分别计算. #include<bits/std ...

  5. 【伪暴力+智商剪枝】Codeforces Round #489 (Div. 2) D

    失踪人口突然回归……orz.题解还是有必要写的,虽然估计只有自己(?自己也不一定看得懂)看得懂. 题目链接:http://codeforces.com/contest/992/problem/D 题目 ...

  6. 图形管线之旅 Part4

    原文:<A trip through the Graphics Pipeline 2011> 翻译:往昔之剑   转载请注明出处   欢迎回来.上个部分是关于vertex shader的, ...

  7. Linux_x64_Pwn溢出漏洞

    linux_64与linux_86的区别 linux_64与linux_86的区别主要有两点: 首先是内存地址的范围由32位变成了64位 但是可以使用的内存地址不能大于0x00007fffffffff ...

  8. Linux-数据库1

    数据库介绍 数据库(database,DB)是指长期存储在计算机内的,有组织,可共享的数据的集合.数据库中的数据按一定的数学模型组织.描述和存储,具有较小的冗余,较高的数据独立性和易扩展性,并可为各种 ...

  9. 范浩强treap 普通平衡树

    增加Split(分裂),Merge(合并)操作,非常好写,时间也不比普通treap慢什么. #include<bits/stdc++.h> using namespace std; str ...

  10. POJ 2378 Tree Cutting 3140 Contestants Division (简单树形dp)

    POJ 2378 Tree Cutting:题意 求删除哪些单点后产生的森林中的每一棵树的大小都小于等于原树大小的一半 #include<cstdio> #include<cstri ...