前言

Executors

  Executors 是一个Java中的工具类。提供工厂方法来创建不同类型的线程池。

  

 常用方法:

   1.newSingleThreadExecutor

     介绍:创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。
此线程池保证所有任务的执行顺序按照任务的提交顺序执行。

    优点:单线程的线程池,保证线程的顺序执行

    缺点:不适合并发

  2.newFixedThreadPool

     介绍:创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。

    优点:固定大小线程池,超出的线程会在队列中等待

    缺点:不支持自定义拒绝策略,大小固定,难以扩展

  3.newCachedThreadPool

     介绍:创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。

    优点:很灵活,弹性的线程池线程管理,用多少线程给多大的线程池,不用后及时回收,用则新建

    缺点:一旦线程无限增长,会导致内存溢出

  4.newScheduledThreadPool

     介绍:创建一个定长线程池,支持定时及周期性任务执行

    优点:一个固定大小线程池,可以定时或周期性的执行任务

    缺点:任务是单线程方式执行,一旦一个任务失败其他任务也受影响

  总结

   1)以上线程池都不支持自定义拒绝策略。

  2)newFixedThreadPool 和 newSingleThreadExecutor:

    主要问题是堆积的请求处理队列可能会耗费非常大的内存,甚至 OOM。

  3)newCachedThreadPool 和 newScheduledThreadPool:

    主要问题是线程数最大数是 Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至 OOM。

ThreadPoolExecutor

阿里巴巴的JAVA开发手册推荐用ThreadPoolExecutor创建线程池。集以上优点于一身。

public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler);

  参数解释:

  corePoolSize : 线程池核心池的大小。

  maximumPoolSize : 线程池的最大线程数。

  keepAliveTime : 当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间。

  unit : keepAliveTime 的时间单位。

  workQueue : 用来储存等待执行任务的队列。

  threadFactory : 线程工厂。

  handler  拒绝策略。

  原理:

  有请求时,创建线程执行任务,当线程数量等于corePoolSize时,请求加入阻塞队列里,当队列满了时,接着创建线程,线程数等于maximumPoolSize。 当任务处理不过来的时候,线程池开始执行拒绝策略。

  阻塞队列:

  ArrayBlockingQueue :一个由数组结构组成的有界阻塞队列。

  LinkedBlockingQueue :一个由链表结构组成的有界阻塞队列。

  PriorityBlockingQueue :一个支持优先级排序的无界阻塞队列。

  DelayQueue: 一个使用优先级队列实现的无界阻塞队列。

  SynchronousQueue: 一个不存储元素的阻塞队列。

  LinkedTransferQueue: 一个由链表结构组成的无界阻塞队列。

  LinkedBlockingDeque: 一个由链表结构组成的双向阻塞队列。

  拒绝策略:

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

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

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

  ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务。

Demo

 1 package com.xxx;
2
3 import com.google.common.util.concurrent.ThreadFactoryBuilder;
4
5 import java.util.concurrent.*;
6
7 /**
8 * 线程池
9 * @author xhq
10 */
11 public class ThreadPoolService {
12
13 /**
14 * 自定义线程名称,方便的出错的时候溯源
15 */
16 private static ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("test-pool-%d").build();
17
18 /**
19 * corePoolSize 线程池核心池的大小
20 * maximumPoolSize 线程池中允许的最大线程数量
21 * keepAliveTime 当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间
22 * unit keepAliveTime 的时间单位
23 * workQueue 用来储存等待执行任务的队列
24 * threadFactory 创建线程的工厂类
25 * handler 拒绝策略类,当线程池数量达到上线并且workQueue队列长度达到上限时就需要对到来的任务做拒绝处理
26 */
27 private static ExecutorService service = new ThreadPoolExecutor(
28 4,
29 40,
30 0L,
31 TimeUnit.MILLISECONDS,
32 new LinkedBlockingQueue<>(1024),
33 namedThreadFactory,
34 new ThreadPoolExecutor.AbortPolicy()
35 );
36
37 /**
38 * 获取线程池
39 * @return 线程池
40 */
41 public static ExecutorService getEs() {
42 return service;
43 }
44
45 /**
46 * 使用线程池创建线程并异步执行任务
47 * @param r 任务
48 */
49 public static void newTask(Runnable r) {
50 service.execute(r);
51 }
52 }

按照阿里巴巴规范创建Java线程池的更多相关文章

  1. 创建Java线程池

    线程池的作用: 线程池作用就是限制系统中执行线程的数量. 根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果:少了浪费了系统资源,多了造成系统拥挤效率不高.用线程池控制线程数量,其他线 ...

  2. Java线程池应用

    Executors工具类用于创建Java线程池和定时器. newFixedThreadPool:创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程.在任意点,在大多数 nThread ...

  3. Java线程池七个参数详解

    Java多线程开发时,常常用到线程池技术,这篇文章是对创建java线程池时的七个参数的详细解释. 从源码中可以看出,线程池的构造函数有7个参数,分别是corePoolSize.maximumPoolS ...

  4. 使用Java 线程池的利弊及JDK自带六种创建线程池的方法

    1. 为什么使用线程池 诸如 Web 服务器.数据库服务器.文件服务器或邮件服务器之类的许多服务器应用程序都面向处理来自某些远程来源的大量短小的任务.请求以某种方式到达服务器,这种方式可能是通过网络协 ...

  5. Java多线程01(Thread类、线程创建、线程池)

    Java多线程(Thread类.线程创建.线程池) 第一章 多线程 1.1 多线程介绍 1.1.1 基本概念 进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于 ...

  6. java线程池之一:创建线程池的方法

    在Java开发过程中经常需要用到线程,为了减少资源的开销,提高系统性能,Java提供了线程池,即事先创建好线程,如果需要使用从池中取即可,Java中创建线程池有以下的方式, 1.使用ThreadPoo ...

  7. java线程池及创建多少线程合适

    java线程池 1.以下是ThreadPoolExecutor参数完备构造方法: public ThreadPoolExecutor(int corePoolSize,int maximumPoolS ...

  8. 面试题-关于Java线程池一篇文章就够了

    在Java面试中,线程池相关知识,虽不能说是必问提,但出现的频次也是非常高的.同时又鉴于公众号"程序新视界"的读者后台留言让写一篇关于Java线程池的文章,于是就有本篇内容,本篇将 ...

  9. java 线程池(线程的复用)

    一. 线程池简介 1. 线程池的概念: 线程池就是首先创建一些线程,它们的集合称为线程池.使用线程池可以很好地提高性能,线程池在系统启动时即创建大量空闲的线程,程序将一个任务传给线程池,线程池就会启动 ...

随机推荐

  1. [源码分析] Dynomite 分布式存储引擎 之 DynoJedisClient(1)

    [源码分析] Dynomite 分布式存储引擎 之 DynoJedisClient(1) 目录 [源码分析] Dynomite 分布式存储引擎 之 DynoJedisClient(1) 0x00 摘要 ...

  2. D-DP

    必备知识 ​ 树链剖分,最大权独立集(即没有上司的舞会(树上DP)),矩阵乘法; D-DP 模版简述 ​ 模板 ​ 关于动态DP,其实是关于一类动态修改点权的问题,但是很难去处理; ​ 我们平常的DP ...

  3. Codeforces Round #652 (Div. 2) D. TediousLee(dp)

    题目链接:https://codeforces.com/contest/1369/problem/D 题意 最初有一个结点,衍生规则如下: 如果结点 $u$ 没有子结点,添加 $1$ 个子结点 如果结 ...

  4. hdu5501 The Highest Mark

    Problem Description The SDOI in 2045 is far from what it was been 30 years ago. Each competition has ...

  5. nuoyanli 520 Let‘s play computer game

    H题 描述 xxxxxxxxx在疫情期间迷上了一款游戏,这个游戏一共有nnn个地点(编号为1--n1--n1--n),他每次从一个地点移动到另外一个地点需要消耗 一定的能量,每一个地点都有一些珠宝,输 ...

  6. 手动编译Selenium源码

    起因 Selenium ChromeDriver和Chrome升级到最新v81版本,同时需要将Selenium3.3.1升级到3.141.59. Selenium本身不支持https,所以修改源码用于 ...

  7. Dapr 已在塔架就位 将发射新一代微服务

    微服务是云原生架构的核心,通常使用Kubernetes 来按需管理服务扩展. 微软一直走在 Cloud Native Computing Foundation的 最前沿,并通过使用Kubernetes ...

  8. 解决M1 MacBook无法使用pip安装Numpy

    问题描述 Python官方已发布支持M1 Apple Silicon的版本,但是在使用pip包管理工具安装一些依赖时发生了错误,这里面就包括在科学计算领域常用的numpy.pandas等.目前可以通过 ...

  9. codeforces 7D

    D. Palindrome Degree time limit per test 1 second memory limit per test 256 megabytes input standard ...

  10. codeforces 5C

    C. Longest Regular Bracket Sequence time limit per test 2 seconds memory limit per test 256 megabyte ...