常用方法

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接口。

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger; public class UseThreadPoolExecutor2 implements Runnable{ private static AtomicInteger count = new AtomicInteger(0); @Override
public void run() {
try {
int temp = count.incrementAndGet();
System.out.println("任务" + temp);
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} public static void main(String[] args) throws Exception{
//System.out.println(Runtime.getRuntime().availableProcessors());
BlockingQueue<Runnable> queue =
//new LinkedBlockingQueue<Runnable>();
new ArrayBlockingQueue<Runnable>(10);
ExecutorService executor = new ThreadPoolExecutor(
5, //core
10, //max
120L, //2fenzhong
TimeUnit.SECONDS,
queue); for(int i = 0 ; i < 20; i++){
executor.execute(new UseThreadPoolExecutor2());
}
Thread.sleep(1000);
System.out.println("queue size:" + queue.size()); //输出结果是10,说明在1秒的时候还有10个线程入队等待
Thread.sleep(2000);
} }

重点看一下自定义策略

public class UseThreadPoolExecutor1 {

    public static void main(String[] args) {
/**
* 在使用有界队列时,若有新的任务需要执行,如果线程池实际线程数小于corePoolSize,则优先创建线程,
* 若大于corePoolSize,则会将任务加入队列,
* 若队列已满,则在总线程数不大于maximumPoolSize的前提下,创建新的线程,
* 若线程数大于maximumPoolSize,则执行拒绝策略。或其他自定义方式。
*
*/
ThreadPoolExecutor pool = new ThreadPoolExecutor(
1, //coreSize
2, //MaxSize
60, //
TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(3) //指定一种队列 (有界队列)
//new LinkedBlockingQueue<Runnable>()
, new MyRejected()
//, new DiscardOldestPolicy()
); MyTask mt1 = new MyTask(1, "任务1");
MyTask mt2 = new MyTask(2, "任务2");
MyTask mt3 = new MyTask(3, "任务3");
MyTask mt4 = new MyTask(4, "任务4");
MyTask mt5 = new MyTask(5, "任务5");
MyTask mt6 = new MyTask(6, "任务6"); pool.execute(mt1);
pool.execute(mt2);
pool.execute(mt3);
pool.execute(mt4);
pool.execute(mt5);
pool.execute(mt6); pool.shutdown(); }
}
import java.net.HttpURLConnection;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor; public class MyRejected implements RejectedExecutionHandler{ public MyRejected(){
} @Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
System.out.println("自定义处理..");
System.out.println("当前被拒绝任务为:" + r.toString()); } }
public class MyTask implements Runnable {

    private int taskId;
private String taskName; public MyTask(int taskId, String taskName){
this.taskId = taskId;
this.taskName = taskName;
} public int getTaskId() {
return taskId;
} public void setTaskId(int taskId) {
this.taskId = taskId;
} public String getTaskName() {
return taskName;
} public void setTaskName(String taskName) {
this.taskName = taskName;
} @Override
public void run() {
try {
System.out.println("run taskId =" + this.taskId);
Thread.sleep(5*1000);
//System.out.println("end taskId =" + this.taskId);
} catch (InterruptedException e) {
e.printStackTrace();
}
} public String toString(){
return Integer.toString(this.taskId);
} }

架构师养成记--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. Java中日期的转化

    4.如何取得年月日.小时分秒? 创建java.util.Calendar实例(Calendar.getInstance()),调用其get()方法传入不同的参数即可获得参数所对应的值,如:calend ...

  2. Css3新特性总结之边框与背景(一)

    本系列主要总结Css3一些新特性的认识,来源于<css揭秘>书. 一.半透明边框 css3最好用hsla,而不是rgba,hsla是:h:颜色值(0~360):s:饱合度(0%~100%) ...

  3. OC多态

    要点: 1.多种形态,引用的多种形态对于一个引用变量,可以指向任何类的对象.对于一个父类的引用(类与类之间有一种继承关系),可以指向子类,也可以指向本类,指向的类型不同.当通过此引用向对象发送消息,调 ...

  4. 嵌入式:J-link刷固件(坑)

    1.上电,短接ERASE,>10秒后,拔USB. 2.短接TST,上电,>10秒后,拔USB. 3.安装驱动.(看别人教程,下载到INF文件,WIN7不能右击安装,好,换虚拟机XP) 4. ...

  5. ExtPB.Net:窗体应用技巧(2)在树形导航下打开弹出的win窗口

    ExtPB.Net的demo程序有个树形导航菜单,里面的菜单打开的窗口放在右边的TabStrip控件中.我们可以设计win通过导航打开,但有时我们希望以弹出窗口的形式打开它,但怎么办呢?现在可以这样修 ...

  6. javascript - 状态模式 - 简化分支判断流程

    状态模式笔记   当一个对象的内部状态发生改变时,会导致行为的改变,这像是改变了对象   状态模式既是解决程序中臃肿的分支判断语句问题,将每个分支转化为一种状态独立出来,方便每种状态的管理又不至于每次 ...

  7. shell两数之间的算术运算

    #!/bin/bash read -p "请输入第一个数:" a read -p "请输入第二个数:" b echo "$a+$b=$[$a+$b]& ...

  8. android OnTouchListener 按下与抬起

    写法一: private OnTouchListener pressOnTouchListener = new OnTouchListener(){ @Override public boolean ...

  9. android Broadcast广播消息代码实现

    我用的是Fragment , 发送写在一个类中,接收写在另外一个类的内部类中.代码动态实现注册. 代码: myReceiver = new zcd.netanything.MyCar.myReceiv ...

  10. Junit mockito解耦合测试

    Mock测试是单元测试的重要方法之一. 1.相关网址 官网:http://mockito.org/ 项目源码:https://github.com/mockito/mockito api:http:/ ...