Java并发编程:线程池的使用
整理自:博客园-海子-http://www.cnblogs.com/dolphin0520/p/3932921.html

1、什么是线程池,为什么要使用线程池:

  1.1、线程池是线程的集合,里面的线程可以重复使用:java在java.util.concurrent下提供了一个Executor接口及其实现,用于创建管理线程池;线程池是指在初始化一个多线程应用时创建一个线程集合,再需要执行新的任务时,重复使用这些线程,而不是去创建新线程。

  1.2、(1)缩短线程的创建和销毁时间,提高程序的性能;

     (2)根据系统的承受能力,调整线程池中工作线程的数目,防止开销过大造成宕机

  1.3、常用的几种线程池:java doc不建议我么直接使用ThreadPoolExecutor创建线程池,而是使用Executors的静态方法创建;

    (1):Executors.newCachedThreadPool(); 可缓存线程池,可根据需要创建新线程,终止超过60秒空闲的线程。

    (2):Executors.newSingleThreadExecutor(); 只有一个单线程,串行执行所有任务。

    (3):Executors.newFixedThreadPool(int):固定线程数线程池,达到固定数量后不新建也不消除。

2、Java中的ThreadPoolExecutor类   

  2.1、主要参数:corePoolSize:核心池的大小;maximumPoolSize:最大线程数;keepAliveTime:无任务时线程保持多久会终止;unit:KeepAliveTime的时间单位;workQueue:阻塞队列,存储等待执行的任务;threadFactory线程工厂用来创建线程;hander:拒绝处理任务时的策略;   2.2、继承关系:ThreadPoolExecutor继承自AbstractExecutorService实现了ExecutorService接口继承了Executor接口;   2.3、ThreadPoolExecutor中的主要方法:
    execute():提交任务
    submit():提交任务并返回结果Future;
    shutdown()shutdownNow():关闭线程池;
  2.4、线程池的状态:
    Running(创建时运行)->ShutDown(调用shutdown)/Stop(调用ShutDownNow状态)->Terminated(上一状态,所有线程已销毁,缓存队列已经清空);
  2.5、任务的执行:
    【1】线程池有线程(<corePoolSize)空闲,来任务给空闲线程;
    【2】CorePoolSize已满,尝试将任务进入等待队列,若不成功(workQueue已满)尝试新建线程去执行该任务;
    【3】当前线程池数量达到maximumPoolSize,再来的任务采取拒绝策略(hander)处理任务;
    【4】线程数量超过maximumPoolSize时,若空闲线程的空闲时间超过了keepAliveTime,线程被终止,知道线程数量不大于CorePoolSize;如果允许核心线程设置KeepAliveTime,那么核心线程空闲一定时间后也会被终止。

  2.6、任务缓存队列workQueue及其排队策略:

    workQueue用来存放等待执行的任务,类型为BlockingQueue<Runnable>通常取一下三种类型:

    (1):ArrayBlockingQueue:基于数组的,先进先出,需要指名大小;

    (2):LinkedBlockingQueue:基于链表的先进先出队列,默认大小Integer.MAX_VALUE

    (3):synchronousQueue:不保存任务,直接开启新线程去执行任务。

  2.7、任务拒绝策略:线程池任务缓存队列workQueue以满,且线程池内线程数目达到maximumPoolSize:

    (1):ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。

    (2):ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。

    (3):ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)

    (4):ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务

  2.8、关闭:shutdown()等待所有任务结束,且不接受新任务;shutdownNow():立即关闭,尝试打断正在执行的任务,清空缓存队列。

  2.9、线程池容量动态调整:setCorePoolSize()和setMaximumPoolSize();

3、:java中ThreadPoolExecutor的使用实例;

  

public class Test {
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 200, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<Runnable>(5)); for(int i=0;i<15;i++){
MyTask myTask = new MyTask(i);
executor.execute(myTask);
System.out.println("线程池中线程数目:"+executor.getPoolSize()+",队列中等待执行的任务数目:"+
executor.getQueue().size()+",已执行玩别的任务数目:"+executor.getCompletedTaskCount());
}
executor.shutdown();
}
}
class MyTask implements Runnable {
private int taskNum; public MyTask(int num) {
this.taskNum = num;
} @Override
public void run() {
System.out.println("正在执行task "+taskNum);
try {
Thread.currentThread().sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("task "+taskNum+"执行完毕");
}
}
结果:
正在执行task 0
线程池中线程数目:1,队列中等待执行的任务数目:0,已执行玩别的任务数目:0
线程池中线程数目:2,队列中等待执行的任务数目:0,已执行玩别的任务数目:0
正在执行task 1
线程池中线程数目:3,队列中等待执行的任务数目:0,已执行玩别的任务数目:0
正在执行task 2
线程池中线程数目:......

4、java.util.concurrent.ThreadPoolExecutor的继承关系

  

Java并发机制(7)--线程池ThreadPoolExecutor的使用的更多相关文章

  1. Java并发编程:线程池ThreadPoolExecutor

    多线程的程序的确能发挥多核处理器的性能.虽然与进程相比,线程轻量化了很多,但是其创建和关闭同样需要花费时间.而且线程多了以后,也会抢占内存资源.如果不对线程加以管理的话,是一个非常大的隐患.而线程池的 ...

  2. Java并发编程:线程池的使用

    Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...

  3. Java并发编程:线程池的使用(转)

    Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...

  4. (转)Java并发编程:线程池的使用

    背景:线程池在面试时候经常遇到,反复出现的问题就是理解不深入,不能做到游刃有余.所以这篇博客是要深入总结线程池的使用. ThreadPoolExecutor的继承关系 线程池的原理 1.线程池状态(4 ...

  5. Java并发编程:线程池的使用(转载)

    转载自:https://www.cnblogs.com/dolphin0520/p/3932921.html Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实 ...

  6. Java并发编程:线程池的使用(转载)

    文章出处:http://www.cnblogs.com/dolphin0520/p/3932921.html Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实 ...

  7. [转]Java并发编程:线程池的使用

    Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...

  8. 【转】Java并发编程:线程池的使用

    Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...

  9. 13、Java并发编程:线程池的使用

    Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...

  10. [转] 引用 Java自带的线程池ThreadPoolExecutor详细介绍说明和实例应用

    PS: Spring ThreadPoolTaskExecutor vs Java Executorservice cachedthreadpool 引用 [轰隆隆] 的 Java自带的线程池Thre ...

随机推荐

  1. python控制浏览器上传文件

    自动化爬虫方法和库很多,难点大多数在登录.可以大致分为:普通验证码,扫码登录,QQ一键登录,拖动验证,无痕验证,人工识别(比如12306登录) 万能大法可以破解一切以上需求,自动控制浏览器行为 参考文 ...

  2. vue如何获取thymeleaf渲染的input值?

    写项目时前端用了vue+模板引擎用了thymeleaf,然后有一个输入框取值问题让我很纠结,问题如下: <input class="count-num" type=" ...

  3. Remix本地化,加载本地合约文件,本地链接Remix

    智能合约IDE,在线的比较卡,而且切换网络面临文件丢失的风险,选择本地搭建Solidity本地编辑环境,Remix-IDE + Remixd组合,加载本地合约代码.这里用到两个工具: Remix ID ...

  4. 使用fireworks解决图片隐写的问题

    同样也可以用ps来解决图层间隐写的问题

  5. web报表设计器在线制作炫酷图表

    相信很多人都看过这些大屏的图表,是不是感觉效果很酷炫,做起来会很复杂,按照传统的方式去做,使用数据分析工具结合ps美化可能耗时要数月才能做出来.但这个时候用Smartbi自助仪表盘功能,全方位的满足各 ...

  6. 厌倦了excel绘制地图的繁琐操作,来看看这款可视化地图神器!

    在现代生活中,地图无论对于社会主义建设.国防.运输以至旅行都是不可缺少的.要学会正确地使用地图,必须学会如何绘制地图. 最近我发现了一款好用的可视化地图神器,比excel做地图可视化好一万倍!其实呢, ...

  7. 【C#多态】as 类型检测(原理分析) ---用于多态检

    as(OpCodes.Castclass)功能:测试对象引用(O 类型)是否为特定类的实例.相当于:expression is type ? (type)expression : (type)null ...

  8. 动态语言运行时(DLR)

    前言 为了让C#.Visual Basic等.NET编程语言能具备动态编程语言的特性,.NET 4.0引入了一个"DLR(Dynamic Language Runtime:动态语言运行时)& ...

  9. Linux概述及简单命令

    Linux概述及简单命令 转自https://www.cnblogs.com/ayu305/p/Linux_basic.html 一.准备工作 1.环境选择:VMware\阿里云服务器 2.Linux ...

  10. GBDT 梯度提升决策树简述

    首先明确一点,gbdt 无论用于分类还是回归一直都是使用的CART 回归树.不会因为我们所选择的任务是分类任务就选用分类树,这里面的核心是因为gbdt 每轮的训练是在上一轮的训练的残差基础之上进行训练 ...