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. .NET Core Dto映射(AutoMapper)

    .Net Core Dto映射(AutoMapper) 我们假设一个场景, 采用EF Core+Web Api, 这时候可能会出现EF Core中的Entity Model和在项目中使用的Model之 ...

  2. python虚拟环境与伪静态网页

    目录 一:python虚拟环境 1.本地虚拟环境 1.创建虚拟环境 2.venv表示虚拟环境标志 3.虚拟环境下载django 4.使用虚拟环境 二:伪静态(了解) 1.什么是伪静态网页? 2.为什么 ...

  3. C语言memcpy()函数和memmove()函数

    C语言memcpy()函数和memmove()函数 关于 memcpy() 函数,请先看链接. memcpy() 函数和 memmove() 函数的函数原型如下: void* memcpy(void ...

  4. 服务器CPU很高-怎么办(Windbg使用坑点)

    最近,碰到了一个线上CPU服务器很高的问题,并且也相当紧急,接到这个任务后,我便想到C#性能分析利器,Windbg. 终于在折腾半天之后,找出了问题,成功解决,这里就和大家分享一下碰到的问题. 问题1 ...

  5. 分布式系统下的CAP定理

    本文参考EricBrewer博客加上自己的理解整理. CAP定理又被成为布鲁尔定理,是加州大学计算机科学家埃里克·布鲁尔提出来的猜想,后来被证明成为分布式计算领域公认的定理. CAP定义,在高并发的场 ...

  6. Python:PIL(三)——Image

    学习自:PIL官方文档--Image (2条消息) Python图像处理PIL各模块详细介绍_章子雎的博客-CSDN博客 一.Image模块 1.open 用法 open(fp,mode='r',fo ...

  7. (第二章第二部分)TensorFlow框架之读取图片数据

    系列博客链接: (第二章第一部分)TensorFlow框架之文件读取流程:https://www.cnblogs.com/kongweisi/p/11050302.html 本文概述: 目标 说明图片 ...

  8. C#10新特性-全局和隐式usings

    .NET 6发布后支持C#10,C# 10 向 C# 语言添加了很多功能,今天我们分享一下全局和隐式usings的使用: using 指令简化了使用命名空间的方式. C# 10 包括一个新的全局 us ...

  9. WPF优秀组件推荐之Stylet(二)

    上一篇文章介绍了Stylet的一些基本功能,本篇将介绍一些深入一点的功能. 依赖注入 在Bootstrapper 类中注入需要的对象: public class Bootstrapper : Boot ...

  10. linux作业--第五周

    1.简述osi七层模型和TCP/IP五层模型 一.OSI参考模型 (1) OSI的来源 OSI(Open System Interconnect),即开放式系统互联. 一般都叫OSI参考模型,是ISO ...