常用方法

Executors.newFiexdPool(int nThreads);固定线程数量的线程池;

Executors.newSingleThreadExecutor();单个线程的线程池;

Executors.newCachedThreadPool();根据实际情况调整线程个数的线程池;每个线程空闲时间60s,过时自动回收;

Executors.newScheduleThreadPool();固定数量线程池,每个线程都可显现定时器。

以上几个线程池都是由ThreadPoolExecutor构造出来的

ThreadPoolExecutor构造方法概述:

ThreadPoolExecutor(

  int corePoolSize,//核心线程数,线程池刚初始化的时候实例化线程个数

  int maximumPoolSize,//最大线程数

  long keepLongTime,//空闲时间,过时回收

  TimeUnit unit,//时间单位

  BlockingQueue<Runable> worker,//线程暂缓处

  ThreadFactory threadFactory,

  RejectExecuteHandle handle//拒绝执行的方法

)

Executors.newScheduledThreadPool

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(10);
scheduler.scheduleWithFixedDelay(command, 1, 3, TimeUnit.SECONDS);

command是Thread对象,1后执行,每3秒执行一次。

自定义线程池的使用

ThreadPoolExecutor pool = new ThreadPoolExecutor(...);

传的参数中,队列是什么类型很重要

有界队列:当前线程数小于corePoolSize,线程立即执行;大于coreSize,并小于maximumPoolSize,线程放入队列;如果队列满了,就执行拒绝方法。

无界队列:除非资源被耗尽,否则不会发生线程被拒绝的情况。以corePoolSize为准,当前线程数大于corePoolSize,线程就会被加入队列。

注:pool.shutdown();不会立即把线程池关闭,而是等线程池中的线程都执行完了,线程池才会关闭。

拒绝策略

AbortPolicy:系统跑出异常,系统继续执行;

discardOldest:丢弃最老的任务,再执行当前新任务;

discardPolicy:丢弃无法执行的任务,不给于任何处理;

callerRunsPolicy:只要线程没有关,会将当前的线程先执行;

自定义策略实现RejectedExecutionHandler接口。

  1. import java.util.concurrent.ArrayBlockingQueue;
  2. import java.util.concurrent.BlockingQueue;
  3. import java.util.concurrent.ExecutorService;
  4. import java.util.concurrent.LinkedBlockingQueue;
  5. import java.util.concurrent.ThreadPoolExecutor;
  6. import java.util.concurrent.TimeUnit;
  7. import java.util.concurrent.atomic.AtomicInteger;
  8.  
  9. public class UseThreadPoolExecutor2 implements Runnable{
  10.  
  11. private static AtomicInteger count = new AtomicInteger(0);
  12.  
  13. @Override
  14. public void run() {
  15. try {
  16. int temp = count.incrementAndGet();
  17. System.out.println("任务" + temp);
  18. Thread.sleep(2000);
  19. } catch (InterruptedException e) {
  20. e.printStackTrace();
  21. }
  22. }
  23.  
  24. public static void main(String[] args) throws Exception{
  25. //System.out.println(Runtime.getRuntime().availableProcessors());
  26. BlockingQueue<Runnable> queue =
  27. //new LinkedBlockingQueue<Runnable>();
  28. new ArrayBlockingQueue<Runnable>(10);
  29. ExecutorService executor = new ThreadPoolExecutor(
  30. 5, //core
  31. 10, //max
  32. 120L, //2fenzhong
  33. TimeUnit.SECONDS,
  34. queue);
  35.  
  36. for(int i = 0 ; i < 20; i++){
  37. executor.execute(new UseThreadPoolExecutor2());
  38. }
  39. Thread.sleep(1000);
  40. System.out.println("queue size:" + queue.size()); //输出结果是10,说明在1秒的时候还有10个线程入队等待
  41. Thread.sleep(2000);
  42. }
  43.  
  44. }

重点看一下自定义策略

  1. public class UseThreadPoolExecutor1 {
  2.  
  3. public static void main(String[] args) {
  4. /**
  5. * 在使用有界队列时,若有新的任务需要执行,如果线程池实际线程数小于corePoolSize,则优先创建线程,
  6. * 若大于corePoolSize,则会将任务加入队列,
  7. * 若队列已满,则在总线程数不大于maximumPoolSize的前提下,创建新的线程,
  8. * 若线程数大于maximumPoolSize,则执行拒绝策略。或其他自定义方式。
  9. *
  10. */
  11. ThreadPoolExecutor pool = new ThreadPoolExecutor(
  12. 1, //coreSize
  13. 2, //MaxSize
  14. 60, //
  15. TimeUnit.SECONDS,
  16. new ArrayBlockingQueue<Runnable>(3) //指定一种队列 (有界队列)
  17. //new LinkedBlockingQueue<Runnable>()
  18. , new MyRejected()
  19. //, new DiscardOldestPolicy()
  20. );
  21.  
  22. MyTask mt1 = new MyTask(1, "任务1");
  23. MyTask mt2 = new MyTask(2, "任务2");
  24. MyTask mt3 = new MyTask(3, "任务3");
  25. MyTask mt4 = new MyTask(4, "任务4");
  26. MyTask mt5 = new MyTask(5, "任务5");
  27. MyTask mt6 = new MyTask(6, "任务6");
  28.  
  29. pool.execute(mt1);
  30. pool.execute(mt2);
  31. pool.execute(mt3);
  32. pool.execute(mt4);
  33. pool.execute(mt5);
  34. pool.execute(mt6);
  35.  
  36. pool.shutdown();
  37.  
  38. }
  39. }
  1. import java.net.HttpURLConnection;
  2. import java.util.concurrent.RejectedExecutionHandler;
  3. import java.util.concurrent.ThreadPoolExecutor;
  4.  
  5. public class MyRejected implements RejectedExecutionHandler{
  6.  
  7. public MyRejected(){
  8. }
  9.  
  10. @Override
  11. public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
  12. System.out.println("自定义处理..");
  13. System.out.println("当前被拒绝任务为:" + r.toString());
  14.  
  15. }
  16.  
  17. }
  1. public class MyTask implements Runnable {
  2.  
  3. private int taskId;
  4. private String taskName;
  5.  
  6. public MyTask(int taskId, String taskName){
  7. this.taskId = taskId;
  8. this.taskName = taskName;
  9. }
  10.  
  11. public int getTaskId() {
  12. return taskId;
  13. }
  14.  
  15. public void setTaskId(int taskId) {
  16. this.taskId = taskId;
  17. }
  18.  
  19. public String getTaskName() {
  20. return taskName;
  21. }
  22.  
  23. public void setTaskName(String taskName) {
  24. this.taskName = taskName;
  25. }
  26.  
  27. @Override
  28. public void run() {
  29. try {
  30. System.out.println("run taskId =" + this.taskId);
  31. Thread.sleep(5*1000);
  32. //System.out.println("end taskId =" + this.taskId);
  33. } catch (InterruptedException e) {
  34. e.printStackTrace();
  35. }
  36. }
  37.  
  38. public String toString(){
  39. return Integer.toString(this.taskId);
  40. }
  41.  
  42. }

架构师养成记--11.Executor概述的更多相关文章

  1. 架构师养成记--15.Disruptor并发框架

    一.概述 disruptor对于处理并发任务很擅长,曾有人测过,一个线程里1s内可以处理六百万个订单,性能相当感人. 这个框架的结构大概是:数据生产端 --> 缓存 --> 消费端 缓存中 ...

  2. 架构师养成记--12.Concurrent工具类CyclicBarrier和CountDownLatch

    java.util.concurrent.CyclicBarrier 一组线程共同等待,直到达到一个公共屏障点. 举个栗子,百米赛跑中,所有运动员都要等其他运动员都准备好后才能一起跑(假如没有发令员) ...

  3. 架构师养成记--35.redis集群搭建

    前记:redis哨兵经验之谈.哨兵做主从切换可能要花费一两秒,这一两秒可能会丢失很多数据.解决方法之一是在java代码中做控制,try catch 到 链接断开的异常就sleep 一两秒钟再conti ...

  4. 架构师养成记--22.客户端与服务器端保持连接的解决方案,netty的ReadTimeoutHandler

    概述 保持客户端与服务器端连接的方案常用的有3种 1.长连接,也就是客户端与服务器端一直保持连接,适用于客户端比较少的情况. 2.定时段连接,比如在某一天的凌晨建立连接,适用于对实时性要求不高的情况. ...

  5. 架构师养成记--14.重入锁ReentrantLock 和 读写锁 ReentrantReadWriteLock

    ReentrantLock 有嗅探锁定和多路分支等功能,其实就是synchronized,wait,notify的升级. this锁定当前对象不方便,于是就有了用new Object()来作为锁的解决 ...

  6. 架构师养成记--10.master-worker模式

    master-worker模式是一种并行计算模式,分为master进程和worker进程两个部分,master是担任总管角色,worker才是执行具体任务的地方. 总体流程应该是这样的: 具体一点,代 ...

  7. 架构师养成记--9.future模式讲解

    什么是future模式呢?解释这个概念之前我们先来了解一个场景吧,财务系统的结账功能,这个功能可能是每个月用一次,在这一个月中相关的数据量已经积累得非常大,这一个功能需要调用好几个存储过程来完成.假如 ...

  8. 架构师养成记--8.Queue

    一.ConcurrentLinkedQueue 是一个适合在高并发场景下,无锁,无界的,先进先出原则.不允许为null值,add().offer()加入元素,这两个方法没区别:pull().peek( ...

  9. 架构师养成记--6.单例和多线程、ThreadLocal

    一.ThreadLocal 使用wait/notify方式实现的线程安全,性能将受到很大影响.解决方案是用空间换时间,不用锁也能实现线程安全. 来看一个小例子,在线程内的set.get就是thread ...

随机推荐

  1. 面向云的.net core开发框架

    目录结构 1 为什么搭建面向云的.Net core云开发框架 2 主要设计思路 3 项目解决方案 4 基础设施层 4.1反射工具 4.2多级可换源的配置(上) 42多级可换源的配置(下) 4.3可配置 ...

  2. About 静态代码块,普通代码块,同步代码块,构造代码块和构造函数的纳闷

    构造函数用于给对象进行初始化,是给与之对应的对象进行初始化,它具有针对性,函数中的一种.特点:1:该函数的名称和所在类的名称相同.2:不需要定义返回值类型.3:该函数没有具体的返回值.记住:所有对象创 ...

  3. Qt——组件位置随窗口变化

    当我们用Qt Designer设计界面时,有时会面临这样一个问题:需要在窗口指定位置放置组件,并且当窗口位置大小改变时,该组件相对其父对象的位置是不变的,如下面两幅图所示 ,首先看上面这幅图,注意bu ...

  4. jQuery 中bind(),live(),delegate(),on() 区别(转)

    当我们试图绑定一些事件到DOM元素上的时候,我相信上面这4个方法是最常用的.而它们之间到底有什么不同呢?在什么场合下用什么方法是最有效的呢? 准备知识: 当我们在开始的时候,有些知识是必须具备的: D ...

  5. XTemplate语法基础

    XTemplate 是富逻辑的 KISSY 模板引擎,面向复杂的业务逻辑场景,同时保持高性能和丰富的配置方法,是易学易懂的模板语言. 一个典型的XTemplate模板实例: Hello {{name} ...

  6. Animation

    Animation 效果 用法 1.非常简单,导入两个文件(UIView+SetRect) (UIView+ImageEffects) 源码 github源码:https://github.com/m ...

  7. luke使用

    Luke介绍 Luke是一个方便的索引查看和诊断工具,可以访问Lucene构建的索引文件,显示和修改某些索引内容.能提供: 通过document编号或term浏览索引 查看document内容,可复制 ...

  8. JAVA编程思想(第四版)学习笔记----11.10 Map

    之前学习的是Collection层次的List接口.List层次比较简单,除去与多线程安全相关的CoppyOnWriteArrayList<T>类,这一个类在集中涉及多线程相关知识时候再学 ...

  9. Oracle死锁

    当两个或多个用户相互等待锁定的数据时就会发生死锁,这时这些用户被卡在不能继续处理业务,oracle可以自动检测死锁并解决他们,通过回滚一个死锁中的语句,释放锁定的数据,回滚的话会遇到ora-00060 ...

  10. asp.net mvc 之旅 —— 第五站 从源码中分析asp.net mvc 中的TempData

    在mvc的controller中,我们知道有很多的临时变量存放数据,比如说viewData,viewBag,还有一个比较特殊的tempData,关于前两个或许大家都明白, 基本上是一个东西,就是各自的 ...