前言

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. 用werkzeug实现一个简单的python web框架

    使用工具 Pycharm , Navicat , WebStorm等 使用库 Werkzeug用于实现框架的底层支撑,pymysql用于实现ORM,jinja2用于模板支持,json用于返回json数 ...

  2. CF-559C Gerald and Giant Chess(计数DP)

    给定一个 \(H*W\)的棋盘,棋盘上只有\(N\) 个格子是黑色的,其他格子都是白色的. 在棋盘左上角有一个卒,每一步可以向右或者向下移动一格,并且不能移动到黑色格子中.求这个卒从左上角移动到右下角 ...

  3. AC自动机——看似KMP在跑,其实fail在跳

    先存代码 AC自动机(简单版) #include<bits/stdc++.h> #define maxn 1000007 using namespace std; int n,ans; i ...

  4. 悬线法——有套路的DP

    例题 P1169 [ZJOI2007]棋盘制作 题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8×88 \times ...

  5. k倍区间(解题报告)前缀和简单应用

    测评地址 问题 1882: [蓝桥杯][2017年第八届真题]k倍区间 时间限制: 1Sec 内存限制: 128MB 提交: 351 解决: 78 题目描述 给定一个长度为N的数列,A1, A2, . ...

  6. Codeforces Round #327 (Div. 1) C. Three States

    C. Three States time limit per test 5 seconds memory limit per test 512 megabytes input standard inp ...

  7. POJ 2195 & HDU 1533 Going Home(最小费用最大流)

    这就是一道最小费用最大流问题 最大流就体现到每一个'm'都能找到一个'H',但是要在这个基础上面加一个费用,按照题意费用就是(横坐标之差的绝对值加上纵坐标之差的绝对值) 然后最小费用最大流模板就是再用 ...

  8. 2015ACM/ICPC亚洲区沈阳站-重现赛 M - Meeting (特殊建边,最短路)

    题意:有\(n\)个点,\(m\)个集合,集合\(E_i\)中的点都与集合中的其它点有一条边权为\(t_i\)的边,现在问第\(1\)个点和第\(n\)个点到某个点的路径最短,输出最短路径和目标点,如 ...

  9. Educational DP Contest G - Longest Path (dp,拓扑排序)

    题意:给你一张DAG,求图中的最长路径. 题解:用拓扑排序一个点一个点的拿掉,然后dp记录步数即可. 代码: int n,m; int a,b; vector<int> v[N]; int ...

  10. python代理池的构建5——对mongodb数据库里面代理ip检查

    上一篇博客地址:python代理池的构建4--mongdb数据库的增删改查 一.对数据库里面代理ip检查(proxy_test.py) #-*-coding:utf-8-*- ''' 目的:检查代理I ...