Java基础教程:多线程基础——线程池

线程池

  《阿里巴巴Java开发手册》有如下一则:

  

  说明里介绍的很清楚,总结来说是这样的:

  • 线程的创建和销毁是耗时较长、耗系统资源较多的操作
  • 将线程放到线程池中,方便管理,且提高线程的复用性,即一个线程可以分配给多个任务使用。

  

线程池原理

线程池状态及数量

  线程池运行的状态,并不是用户显式设置的,而是伴随着线程池的运行,由内部来维护。线程池内部使用一个变量维护两个值:运行状态(runState)和线程数量 (workerCount)。在具体实现中,线程池将运行状态(runState)、线程数量 (workerCount)两个关键参数的维护放在了一起,如下代码所示:

private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0)); //运行状态 & 线程数量
private static final int COUNT_BITS = Integer.SIZE - 3; private static final int RUNNING = -1 << COUNT_BITS;
...
private static int ctlOf(int rs, int wc) { return rs | wc; }

  线程状态分为五种:  

  

  线程池的生命周期:

  

任务执行机制

  所有任务的调度都是由execute方法完成的,这部分完成的工作是:检查现在线程池的运行状态、运行线程数、运行策略,决定接下来执行的流程,是直接申请线程执行,或是缓冲到队列中执行,亦或是直接拒绝该任务。其执行过程如下:

  1. 如果正在运行的线程少于corePoolSize线程,请尝试使用给定任务作为其第一个任务来启动新线程。 对addWorker的调用原子地检查runState和workerCount,从而通过返回false来防止在不应该添加线程的情况下发出错误警报。
  2. 如果任务可以成功排队,那么我们仍然需要仔细检查是否应该添加线程(因为现有线程自上次检查后就已死亡)或自进入此方法以来该池已关闭。 因此,我们重新检查状态,并在必要时回滚排队,如果已停止,或者在没有线程的情况下启动新线程。
  3. 如果我们无法将任务排队,则尝试添加一个新线程。 如果失败,则表明我们已关闭或已饱和,因此拒绝该任务。

任务缓存

  线程池的本质是对任务和线程的管理,阻塞队列负责缓存任务,工作线程从队列中获取任务以便执行

说明:阻塞队列(BlockingQueue),即在普通队列的基础上实现以下两个附加操作

  • 当队列满时,队列会阻塞插入元素的线程,直到队列不满。
  • 当队列空时,队列会阻塞获取元素的线程,知道队列不空。

  

参考资料

Java基础教程:多线程基础——线程池的更多相关文章

  1. Java基础学习——多线程之线程池

    1.线程池介绍     线程池是一种线程使用模式.线程由于具有空闲(eg:等待返回值)和繁忙这种不同状态,当数量过多时其创建.销毁.调度等都会带来开销.线程池维护了多个线程,当分配可并发执行的任务时, ...

  2. java 22 - 20 多线程之线程池

    程序启动一个新线程成本是比较高的,因为它涉及到要与操作系统进行交互. 而使用线程池可以很好的提高性能,尤其是当程序中要创建大量生存期很短的线程时,更应该考虑使用线程池. 线程池里的每一个线程代码结束后 ...

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

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

  4. Java 多线程:线程池

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

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

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

  6. C#多线程之线程池篇1

    在C#多线程之线程池篇中,我们将学习多线程访问共享资源的一些通用的技术,我们将学习到以下知识点: 在线程池中调用委托 在线程池中执行异步操作 线程池和并行度 实现取消选项 使用等待句柄和超时 使用计时 ...

  7. 多线程系列 线程池ThreadPool

    上一篇文章我们总结了多线程最基础的知识点Thread,我们知道了如何开启一个新的异步线程去做一些事情.可是当我们要开启很多线程的时候,如果仍然使用Thread我们需要去管理每一个线程的启动,挂起和终止 ...

  8. ExecutorService 建立一个多线程的线程池的步骤

    ExecutorService 建立一个多线程的线程池的步骤: 线程池的作用: 线程池功能是限制在系统中运行的线程数. 依据系统的环境情况,能够自己主动或手动设置线程数量.达到执行的最佳效果:少了浪费 ...

  9. C#多线程之线程池篇3

    在上一篇C#多线程之线程池篇2中,我们主要学习了线程池和并行度以及如何实现取消选项的相关知识.在这一篇中,我们主要学习如何使用等待句柄和超时.使用计时器和使用BackgroundWorker组件的相关 ...

  10. C#多线程之线程池篇2

    在上一篇C#多线程之线程池篇1中,我们主要学习了如何在线程池中调用委托以及如何在线程池中执行异步操作,在这篇中,我们将学习线程池和并行度.实现取消选项的相关知识. 三.线程池和并行度 在这一小节中,我 ...

随机推荐

  1. sql server 中的表值函数和标量值函数

      顾名思义:表值函数返回的是表,而标量值函数可以返回基类型 一.表值函数 用户定义表值函数返回 table 数据类型.对于内联表值函数,没有函数主体:表是单个 SELECT 语句的结果集. 以下示例 ...

  2. Linux rpm安装指定安装路径

    可以使用prefix参数. rpm -i –prefix=/home/gpadmin    greenplum-db-6.0.0-rhel6-x86_64.rpm 将greenplum-db-6.0. ...

  3. YAML_18 ansible 判断和循环

    标准循环 模式一 - name: add several users user: name={{ item }} state=present groups=wheel with_items: - te ...

  4. 桥接模式:探索JDBC底层实现

    一.目录概要 二.问题探究 需求:假设要设计一个电脑商场管理系统的某个模块设计,电脑分为品牌和类型两个纬度,我们应该怎么解决? 按照初学者的思路,利用继承就能简单粗暴的实现,那我们来看下这种思路的设计 ...

  5. luogu 1714

    前缀和 + rmq #include <bits/stdc++.h> const int N = 5e5 + 10; int Pow[30], Log[N]; int n, m; int ...

  6. 洛谷 P1006 传纸条 题解

    P1006 传纸条 题目描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法 ...

  7. 一次 react-router 中遇到的小坑

    react-router Link 标签不生效的问题 废话不多说, 直接上问题, 排解过程和答案 现象: 发现 使用 Link 标签没有 元素的样式和效果, 也不能进行跳转 代码如下: render( ...

  8. Chrome教程(一)NetWork面板分析网络请求

    官方文档:https://developers.google.com/web/tools/chrome-devtools/network/ 1.如何打开 无论是在Windows还是Mac,都可以使用( ...

  9. 备用shell管理方案之butterfly+nginx+https

    安装butterfly+nginx https 1. 安装butterfly yum install python36 python36-pip python36-devel -y pip insta ...

  10. vue的ref试用

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...