什么是线程池?

为了避免系统频繁地创建和销毁线程,我们可以让创建的线程进行复用。
用线程时从线程池中获取,用完以后不销毁线程,而是归还给线程池。

JDK 对线程池的支持

为了更好的控制多线程,JDK 提供了一套线程池框架,结构如下图所示

它们都在 java.util.concurrent 包中。

  • Executor 用来执行任务,它提供了 execute() 方法来执行 Runnable 任务;
  • ThreadPoolExecutor 表示一个线程池;
  • Executors 它是一个静态工厂工厂类,通过它可以取得一个拥有特定功能的线程池;

不同特性的线程池

  1. newFixedThreadPool():返回固定数量的线程池。线程池中的数量始终不变。当有新任务提交时,线程池中若有空闲线程,则立即执行。若没有则放入任务队列中,等待有空闲线程时,处理任务队列中的任务。
  2. newSingleThreadPool():返回只有一个线程的线程池。若有多余一个任务被提交,则放入任务队列中,等待有空闲线程时,按先入先出的顺序执行队列中的任务。
  3. newCachedThreadPool():返回一个可根据实际情况调整线程数量的线程池。这个方法创建出来的线程池可以被无限扩展,并且当需求降低时会自动收缩。
  4. newSingleThreadScheduledExecutor():返回一个 ScheduledExecutorService 对象,线程池大小为 1。ScheduledExecutorService 接口在 ExecutorService 接口之上扩展了在给定时间执行某任务的功能,在某个固定时间延迟之后,或周期性执行某个任务。
  5. newScheduledThreadPool():返回一个 ScheduledExecutorService 对象,并可指定线程数量。
  6. ScheduledExecutorService 并不一定会立即安排执行任务,而是起到了计划任务的作用。
  7. 它主要有一下三个方法:

    1. schedule():会在给定的时间,对任务进行一次调度
    2. scheduleAtFixedRate():创建并执行一个在给定初始延迟后首次启用的定期操作,后续操作具有给定的周期
    3. scheduleWithFixedDelay():创建并执行一个在给定初始延迟后首次启用的定期操作,随后,在每一次执行终止和下一次执行开始之间都存在给定的延迟

示例

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Created by zhengbin on 2017/10/24
*/
public class ExecutorServiceTest {
private static class Task implements Runnable {
public void run() {
System.out.println(System.currentTimeMillis() + ":Thread ID:" + Thread.currentThread().getId());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public static void main(String[] args) {
Task t = new Task();
ExecutorService executorService = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10;i++) {
executorService.execute(t);
}
executorService.shutdown();
}
}

运行结果

1509258535474:Thread ID:11
1509258535474:Thread ID:12
1509258535475:Thread ID:14
1509258535475:Thread ID:15
1509258535475:Thread ID:13
1509258536475:Thread ID:15
1509258536475:Thread ID:11
1509258536475:Thread ID:12
1509258536475:Thread ID:14
1509258536475:Thread ID:13

结果说明

主线程创建了一个固定大小的线程池,线程池的容量是 5。

运行结果输出了运行的时间戳,可以看到,前 5 个任务执行的时间戳与后 5 个任务的时间戳相差了 1000 毫秒。

这说明在这 10 个任务中,是分成 2 批次执行的。这也完全符合一个只有 5 个线程的线程池的行为。

当把线程池改为 newCachedThreadPool() 时,就会将 10 个任务同时执行。

Java多线程系列——线程池简介的更多相关文章

  1. Java多线程系列——线程池原理之 ThreadPoolExecutor

    ThreadPoolExecutor 简介 ThreadPoolExecutor 是线程池类. 通俗的讲,它是一个存放一定数量线程的线程集合.线程池允许多个线程同时运行,同时运行的线程数量就是这个线程 ...

  2. Java多线程与线程池技术

    一.序言 Java多线程编程线程池被广泛使用,甚至成为了标配. 线程池本质是池化技术的应用,和连接池类似,创建连接与关闭连接属于耗时操作,创建线程与销毁线程也属于重操作,为了提高效率,先提前创建好一批 ...

  3. Java 多线程:线程池

    Java 多线程:线程池 作者:Grey 原文地址: 博客园:Java 多线程:线程池 CSDN:Java 多线程:线程池 工作原理 线程池内部是通过队列结合线程实现的,当我们利用线程池执行任务时: ...

  4. java多线程、线程池及Spring配置线程池详解

    1.java中为什么要使用多线程使用多线程,可以把一些大任务分解成多个小任务来执行,多个小任务之间互不影像,同时进行,这样,充分利用了cpu资源.2.java中简单的实现多线程的方式 继承Thread ...

  5. Java多线程和线程池

    转自:http://blog.csdn.net/u013142781/article/details/51387749 1.为什么要使用线程池 在Java中,如果每个请求到达就创建一个新线程,开销是相 ...

  6. Java多线程之线程池详解

    前言 在认识线程池之前,我们需要使用线程就去创建一个线程,但是我们会发现有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因 ...

  7. JAVA多线程(三) 线程池和锁的深度化

    github演示代码地址:https://github.com/showkawa/springBoot_2017/tree/master/spb-demo/spb-brian-query-servic ...

  8. Java多线程-ThreadPool线程池(三)

    开完一趟车完整的过程是启动.行驶和停车,但老司机都知道,真正费油的不是行驶,而是长时间的怠速.频繁地踩刹车等动作.因为在速度切换的过程中,发送机要多做一些工作,当然就要多费一些油. 而一个Java线程 ...

  9. Java多线程(四) 线程池

    一个优秀的软件不会随意的创建.销毁线程,因为创建和销毁线程需要耗费大量的CPU时间以及需要和内存做出大量的交互.因此JDK5提出了使用线程池,让程序员把更多的精力放在业务逻辑上面,弱化对线程的开闭管理 ...

随机推荐

  1. 001.Open-Falcon简介

    一 Open-Falcon简介 监控系统是整个运维环节,乃至整个产品生命周期中最重要的一环,事前及时预警发现故障,事后提供翔实的数据用于追查定位问题.监控系统作为一个成熟的运维产品,相对成熟的解决方案 ...

  2. 工作->离职->考研

    1.工作篇 去年我大三,理论上来说我应该考研,也必须考研,我当时的想法也是这样.但是不知道什么情况,我竟然选择了工作,连我也没想到的反转,可能当时我对自己的技术很自信?我想可能是,有点对自己技术觉得还 ...

  3. PHP7和PHP5在安全上的区别[更新]

    0X01 前言 本篇文章大多为转载,但是修正了一些不正确的说法,对某些功能点的变更指出具体是哪个版本变更,加入了一些小更新. (原文地址:https://www.freebuf.com/article ...

  4. postcss那些事儿

    一.sass和postcsssass.less.stylus,三者是css预处理器,使用预编码来处理css,然后编译成线上需要的css.postcss是处理你写好的css,让你的css更健康,对浏览器 ...

  5. BZOJ.1022.[SHOI2008]小约翰的游戏John(博弈论 Anti-Nim)

    题目链接 Anti-Nim游戏: 先手必胜当且仅当: 1.所有堆的石子数为1,且异或和为0 2.至少有一堆石子数>1,且异或和不为0 简要证明: 对于1:若异或和为1,则有奇数堆:异或和为0,则 ...

  6. Python3正则表达式(2)

    re库常用方法 正则表达式的表示类型: 1.re库采用 raw string 类型(原生字符串类型),不用对转义符再次转义,表示为:r'text' 例如:r'\d{3}-\d{8}' 2.re库采用 ...

  7. Python3练习题系列(05)——设计和调试规则

    If 语句的常见规则 1. 每一个“if 语句”必须包含一个else: 2. 如果这个else 永远都不应该被执行到,因为它本身没有任何意义,那你必须在else 语句后面使用一个叫做die 的函数,让 ...

  8. 基于Grunt构建一个JavaScript库

    现在公认的JavaScript典型项目需要运行单元测试,合并压缩.有些还会使用代码生成器,代码样式检查或其他构建工具. Grunt.js是一个开源工具,可以帮助你完成上面的所有步骤.它非常容易扩展,并 ...

  9. java计算某个坐标是否在范围内

    java电子围栏 圆.矩形.多边形算法 http://blog.csdn.net/deepak192/article/details/79402694/ java-经纬度有关的计算(半径内的经纬度范围 ...

  10. JDBC(4)—Preparedstatement

    功能:使用PreparedStatement操作数据表,其功能与Statement一致,但为何要使用PreparedStatement呢. 一.原因: 1.使用sql语句进行操作数据表时,需要拼写sq ...