引言

我们之前使用线程的时候都是使用 new Thread 来进行线程的创建,但是这样会有一些问题

  • 每次 new Thread 新建对象性能差

  • 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致死机

  • 缺乏更多功能,如定时执行、定期执行、线程中断。

相比 new Thread,Java 提供的四种线程池的好处在于:

  • 重用存在的线程,减少对象创建、消亡的开销,性能佳。

  • 可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。

  • 提供定时执行、定期执行、单线程、并发数控制等功能。

ExecutorService 线程池接口

Java 通过 Executors 提供四种线程池,分别为:

  • newCachedThreadPool:创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。

  • newFixedThreadPool:创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。

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

  • newSingleThreadExecutor:创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

newCachedThreadPool

ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
final int index = i;
try {
Thread.sleep(index * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
} cachedThreadPool.execute(new Runnable() { @Override
public void run() {
System.out.println(index);
}
});
}

线程池为无限大,当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程。

newFixedThreadPool

创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。

ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
for (int i = 0; i < 10; i++) {
final int index = i;
fixedThreadPool.execute(new Runnable() { @Override
public void run() {
try {
System.out.println(index);
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}

因为线程池大小为3,每个任务输出index后sleep 2秒,所以每两秒打印3个数字。

定长线程池的大小最好根据系统资源进行设置。如Runtime.getRuntime().availableProcessors()。

newScheduledThreadPool

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

ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
scheduledThreadPool.schedule(new Runnable() { @Override
public void run() {
System.out.println("delay 3 seconds");
}
}, 3, TimeUnit.SECONDS);

表示延迟3秒执行。

定期执行示例代码如下

scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
@Overridepublic void run() {System.out.println("delay 1 seconds, and excute every 3 seconds");}}, 1, 3, TimeUnit.SECONDS);

表示延迟1秒后每3秒执行一次。

ScheduledExecutorService比Timer更安全,功能更强大

newSingleThreadExecutor

创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
final int index = i;
singleThreadExecutor.execute(new Runnable() { @Override
public void run() {
try {
System.out.println(index);
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}

Java 四种内置线程池的更多相关文章

  1. 线程池的极简用法——内置线程池multiprocessing

    大家好,今天博主来分享一个线程池的小捷径--内置线程池的使用方法 一.背景 说道多线程,对变成层有了解的小伙伴一定不陌生,虽然不知道是什么但是也会从各大网站.面试分享等途径听说过.这里就不做过多的介绍 ...

  2. 为什么阿里Java规约禁止使用Java内置线程池?

    IDEA导入阿里规约插件,当你这样写代码时,插件就会自动监测出来,并给你红线提醒. 告诉你手动创建线程池,效果会更好. 在探秘原因之前我们要先了解一下线程池 ThreadPoolExecutor 都有 ...

  3. Android 四种常见的线程池

    引入线程池的好处 1)提升性能.创建和消耗对象费时费CPU资源 2)防止内存过度消耗.控制活动线程的数量,防止并发线程过多. 我们来看一下线程池的简单的构造 public ThreadPoolExec ...

  4. java内置线程池ThreadPoolExecutor源码学习记录

    背景 公司业务性能优化,使用java自带的Executors.newFixedThreadPool()方法生成线程池.但是其内部定义的LinkedBlockingQueue容量是Integer.MAX ...

  5. Java 四种线程池newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor

    介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端执行一个异步任务你还只是如下new T ...

  6. Java四种线程池

    Java四种线程池newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor 时间:20 ...

  7. (转载)new Thread的弊端及Java四种线程池的使用

    介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端 执行一个异步任务你还只是如下new ...

  8. 线程池是什么?Java四种线程池的使用介绍

    使用线程池的好处有很多,比如节省系统资源的开销,节省创建和销毁线程的时间等,当我们需要处理的任务较多时,就可以使用线程池,可能还有很多用户不知道Java线程池如何使用?下面小编给大家分享Java四种线 ...

  9. Java第三方数据库连接池库-DBCP-C3P0-Tomcat内置连接池

    连接池原理 数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”.预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去.我们可以通过设定连接池 ...

随机推荐

  1. 201871030133-徐作朝 实验二 个人项目—《D{0-1} KP》项目报告

    项目 内容 课程班级博客链接 课程班级博客链接 这个作业要求连接 作业要求链接 我的课程学习目标 (1)掌握软件项目个人开发流程.(2)掌握Github发布软件项目的操作方法. 这个作业在那些方面帮助 ...

  2. 周爱民带你深入剖析JavaScript核心原理

    作为前端工程师必备技能,JavaScript 的重要性不言而喻.虽然易上手,但却有着诸多复杂微妙的机制,想要真正掌握绝非易事. 专栏面向JavaScript语言的实际应用者与深度爱好者,以讲述Java ...

  3. H5 端 rem 适配方案与 viewport 适配

    H5 端 rem 适配方案与 viewport 适配 rem rem 是 CSS3 新增的一个相对单位(root em,根 em) 只根据当前页面 HTML 页面的 font-size 设置,如果根目 ...

  4. Java(133-151)【String类、static、Arrays类、Math类】

    1.字符串概述和特点 string在lang包里面,因此可以直接使用 字符串的内容不可变 2.字符串的构造方法和直接创建 三种构造方法 package cn.itcast.day08.demo01; ...

  5. (十六)VMware Harbor 复制镜像

    Step 1: 点击复制镜像后 Step 2: 填写复制镜像信息 Step 3:在sx628下,会多出一个镜像

  6. editorconfig、eslint、prettier三者的区别、介绍及使用

    每次搭建新项目都少不了这些工具,但时间一久就忘记了,下次搭新项目时又要四处查官方文档,因此特此记录,主要内容是对这三个工具的理解,以及具体使用方式 editorconfig 理解 先看官网的定义: E ...

  7. JMeter 实战案例

    案例1:博客网站后端测试 案例2:JPetStore 应用 案例1:博客网站后端测试 测试目标 测试博客网站后端的常用 HTTP 接口的访问方法. 展示 HTTP 请求的各类使用方法. 展示提取 JS ...

  8. 使用docker快速安装软件

    安装mysql mkdir /opt/mysql /opt/mysql/etc /opt/mysql/data docker run -itd --name mariadb -e MYSQL_ROOT ...

  9. php引入html文件(或php文件)的方法

    php引入html文件(或php文件)的方法 一.使用fopen()函数  此函数主要传入的是头两个参数(第一个是文件地址,第二个是打开方式),可以读取任何一个文本文件,然后用while将fopen函 ...

  10. LA3177长城守卫

    题意:      有n个人围成一个圈,每个人都有r[i]个礼物,任意两个相邻的人的礼物不能有重复的,问满足所有相邻不重复的最少礼物种数是多少?就是问最少多少种礼物能让任意相邻的两个人的礼物不重复. 思 ...