复习并发编程的基础知识之线程池

news2024/11/24 7:15:52
  • 并发编程中,线程池是很重要的一块内容。
    线程池是一种池化技术,线程池、字符串常量池和数据库链接池都属于池化技术。
    使用线程池的好处:
    1.提高了线程的利用率(想一想,我们不可能每打一个电话,就去买一部手机吧?)
    2.提高了程序的响应速度
    3.方便统一管理线程对象
    4.可以控制最大的并发数

线程池的模型如下: 在这里插入图片描述
其实和在银行办理业务是一样的
银行排队办业务模型
对应关系如下:
顾客–》任务
线程池–》银行
线程池中的线程对象–》银行的服务窗口
队列–》座位

在java中我们在使用线程池的时候,

ExecutorService threadPoolExecutor = new ThreadPoolExecutor(3,
                  5, 
                  1L, 
                  TimeUnit.SECONDS, 
                  new ArrayBlockingQueue<>(3)
                , Executors.defaultThreadFactory(), 
                new ThreadPoolExecutor.AbortPolicy());

对应API

 /**
     * Creates a new {@code ThreadPoolExecutor} with the given initial
     * parameters.
     *
     * @param corePoolSize the number of threads to keep in the pool, even
     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
     * @param maximumPoolSize the maximum number of threads to allow in the
     *        pool
     * @param keepAliveTime when the number of threads is greater than
     *        the core, this is the maximum time that excess idle threads
     *        will wait for new tasks before terminating.
     * @param unit the time unit for the {@code keepAliveTime} argument
     * @param workQueue the queue to use for holding tasks before they are
     *        executed.  This queue will hold only the {@code Runnable}
     *        tasks submitted by the {@code execute} method.
     * @param threadFactory the factory to use when the executor
     *        creates a new thread
     * @param handler the handler to use when execution is blocked
     *        because the thread bounds and queue capacities are reached
     * @throws IllegalArgumentException if one of the following holds:<br>
     *         {@code corePoolSize < 0}<br>
     *         {@code keepAliveTime < 0}<br>
     *         {@code maximumPoolSize <= 0}<br>
     *         {@code maximumPoolSize < corePoolSize}
     * @throws NullPointerException if {@code workQueue}
     *         or {@code threadFactory} or {@code handler} is null
     */
 public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

其中线程池的几个重要参数是面试中经常被问的内容。
corePoolSize:核心线程数
maximumPoolSize:最大线程数
keepAliveTime:存活时间
unit:和keepAliveTime成对出现,存活时间的单位
workQueue:the queue to use for holding tasks before they are executed.这个队列用于存放任务,什么样的任务呢?在这些任务被执行之前的任务。也就是说,任务没执行的时候都放在这个阻塞队列中。
threadFactory:线程工厂。
handler:拒绝策略。
在这里插入图片描述
在这里插入图片描述
从上面的这个图会发现,其实线程池是非公平的,因为后面来的任务比先来的在那等着的任务先执行了。

以这个

new ThreadPoolExecutor(3,
                  5, 
                  1L, 
                  TimeUnit.SECONDS, 
                  new ArrayBlockingQueue<>(3) //相当于就三个座位
                , Executors.defaultThreadFactory(), 
                new ThreadPoolExecutor.AbortPolicy());

为例说明:

  1. 当顾客1来的时候,银行创建一个窗口1,那么顾客1发现有窗口1空闲,那么窗口1来为顾客1服务,
    当顾客2来的时候,银行又创建一个窗口2,那么顾客2发现有窗口2空闲,那么窗口2来为顾客2服务,
    当顾客3来的时候,银行又创建一个窗口3,那么顾客3发现有窗口3空闲,那么窗口3来为顾客3服务,
    此时核心窗口数(核心线程数)达到了最大值
    当顾客4来的时候,发现没有窗口,但是座位还有位置,那么坐在座位上等待,
    当顾客5来的时候,发现没有窗口,但是座位还有位置,那么坐在座位上等待,
    当顾客6来的时候,发现没有窗口,但是座位还有位置,那么坐在座位上等待,
    此时座位(阻塞队列)已满
    当顾客7来的时候,发现没有窗口,而且座位也没有位置,这个时候银行行长说:来吧!窗口4你也别歇着了,工作吧!这样窗口4启动,窗口4为顾客7服务,
    当顾客8来的时候,发现没有窗口,而且座位也没有位置,这个时候银行行长又说:来吧!窗口5你也别歇着了,工作吧!这样窗口5启动,窗口5为顾客8服务,
    此时最大窗口数(最大线程数)达到了最大值
    当顾客9来的时候,发现没有窗口,而且座位也没有位置,这个时候,行长对顾客说:我们这里窗口数已经达到了(maximumPoolSize最大线程数),而且座位(BlockingQueue
    workQueue)也满了,我们得使用拒绝策略了(RejectedExecutionHandler
    handler,这种策略是抛出异常Exception in thread “main”
    java.util.concurrent.RejectedExecutionException:…)
    过了一段时间后,
    最后,当没有顾客来的时候了,行长看
    不用那么多窗口了,那么和窗口4和5说,再过1(keepAliveTime)s(unit)的时间你们可以下班了。所以我们称keepAliveTime为存活时间。
package cn.tulingxueyuan.xiaoshanshan.base.threadpool;

import java.util.concurrent.*;

public class MyThreadPool {

    public static void main(String[] args) {
        ExecutorService threadPoolExecutor = new ThreadPoolExecutor(3,
                5, 1l, TimeUnit.SECONDS, new ArrayBlockingQueue<>(2)
                , Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
        try{
            for(int i=0;i<8;i++){
                threadPoolExecutor.execute(()->{
                    System.out.println(Thread.currentThread().getName() + "正在运行。。。。");
                    try {
                        Thread.sleep((int)(Math.random()*100)+1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                });
            }
        }finally {
            threadPoolExecutor.shutdown();
        }



    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/648609.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity编辑器扩展-第三集-添加按钮到组件菜单并且重置组件

第二集链接&#xff1a;Unity编辑器扩展-第二集-按钮排序/分组/放入右键菜单_菌菌巧乐兹的博客-CSDN博客 一、本节目标效果展示 1.把按钮放到组件菜单上 2.做一个类似Reset功能&#xff0c;点一下能改变里面的数据 二、 把按钮放到组件菜单上 如上图&#xff0c;我的的组件名…

echarts 配置相关

echarts更多模板链接 http://chart.majh.top/ 1、echarts.clear()是清空当前实例&#xff0c;会移除实例中所有的组件和图表。 echarts.dispose()是销毁实例&#xff0c;销毁后实例无法再被使用。 this.chart.dispose() this.chart.clear(); // 清空图表2、series虽然是[] 数…

BRC20赛道的刚需基础设施,BrccSwap如何延续新的造富神话?

引言 BRC20代币和去中心化交易所的背景 BRC20代币赛道的刚需SWAP BrccSwap如何延续新的造富神话 结语 引言 随着加密货币市场的不断发展&#xff0c;BRC20代币和去中心化交易所成为了越来越受欢迎的概念。BRC20代币是建立在比特币区块链上的代币&#xff0c;具有高级别的…

一季度亏损47亿,全系降价背后,蔚来能否实现自救?

降价之后&#xff0c;蔚来能否实现自救&#xff1f; 6月12日&#xff0c;蔚来汽车宣布全系车型起售价减 3 万元&#xff1b;新购车首任车主用车权益调整为整车6年或15万公里质保等&#xff1b;免费换电补能不再作为标准用车权益&#xff0c;新用户可灵活选择在家充电或到充换电…

new Vue后整个的流程

文章目录 new Vue后整个的流程Vue.js 创建应用程序流程概述使用 new Vue() 创建Vue 实例流程概述 new Vue后整个的流程 new Vue({el: #app,render: h > h(App),data() {return {message: hello vue}} }).$mount(#app)Vue.js 创建应用程序流程概述 在使用 Vue.js 创建一个应…

Linux:进程管理

进程&#xff1a;为管理程序的运行&#xff0c;操作系统会给每个运行的程序都注册为系统的一个进程&#xff0c;并为每个进程分配一个进程id 查看进程&#xff1a;Linux中可以通过ps命令查看系统中的进程信息&#xff0c;语法&#xff1a; ps [-e -f] -e选项&#xff1a;表示显…

0基础入门---第3章---神经网络(前向传播)

&#x1f31e;欢迎来到深度学习的世界 &#x1f308;博客主页&#xff1a;卿云阁 &#x1f48c;欢迎关注&#x1f389;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f31f;本文由卿云阁原创&#xff01; &#x1f64f;作者水平很有限&#xff0c;如果发现错误&#xff…

退出印度之后,越南制造也有麻烦,苹果摆脱中国制造成幻想

日前媒体报道指苹果在越南的代工厂面临麻烦&#xff0c;由于越南缺乏足够的电力供应&#xff0c;越南的工厂出现断电的问题&#xff0c;工厂生产被迫暂停&#xff0c;最严重的时候连续20天白天无法开工&#xff0c;这对于苹果来说无疑是又一个重大打击。 一、苹果的印度制造计划…

MODNet Background Remover 环境搭建步骤

1、安装 Python 3.8以上 2、安装 CUDA环境 4、下载 MODNet Background Remover 5、解压并进入到 MODNet Background Remover文件夹 6、创建虚拟环境 python -m venv venv7、使用虚拟环境 .\venv\Scripts\activate8、安装依赖包 pip install --upgrade pippip install --upg…

阿里云服务器租用费用_轻量和ECS价格表

2023年阿里云服务器租用费用&#xff0c;阿里云轻量应用服务器2核2G3M带宽轻量服务器一年108元&#xff0c;2核4G4M带宽轻量服务器一年297.98元12个月&#xff0c;阿里云u1服务器2核4G、2核8G、4核8G、8核16G、4核16G、8核64等配置新人3折&#xff0c;云服务器c7、g7和r7均有活…

VMware Horizon 8 运维系列(二)桌面计算机无法访问代理

前言 Horizon 8 在使用即时克隆桌面池,偶尔会出现某个桌面计算机显示“无法访问代理”状态,这时该计算机无法通过客户机来访问。 一、问题描述 1、问题场景 桌面池类型:即时克隆桌面池 2、查看桌面池 查看桌面池,发现有计算机状态为“无法访问代理“,如下图: 二、问题…

回归预测 | MATLAB实现基于BiLSTM-AdaBoost双向长短期记忆网络结合AdaBoost多输入单输出回归预测

回归预测 | MATLAB实现基于BiLSTM-AdaBoost双向长短期记忆网络结合AdaBoost多输入单输出回归预测 目录 回归预测 | MATLAB实现基于BiLSTM-AdaBoost双向长短期记忆网络结合AdaBoost多输入单输出回归预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.MATLAB实现…

全民AI计划:通过langchain给LLM接上落地的大腿

langchain是一个开源项目 github.com/hwchase17/l… 。这个项目在GitHub上已经有45.5K个Star了。此项目由一位叫hwchase17的国外小哥在2022年底发布。 我有理由相信&#xff0c;这个项目是为了对接大语言模型才搞的。 一、企业困境: 如何应用大语言模型 大语言模型(Large La…

渗透专题丨web Top10 漏洞简述(2)

文件包含漏洞 1、漏洞简述 程序在引用文件的时&#xff0c;引用的文件名&#xff0c;用户可控的情况&#xff0c;传入的文件名校验不严&#xff0c;从而操作了预想之外的文件&#xff0c;就有可能导致文件泄漏和恶意的代码注入。这是因为程序开发时候会把重复使用的函数写到归…

springboot启动流程 (1) 流程概览

本文将通过阅读源码方式分析SpringBoot应用的启动流程&#xff0c;不涉及Spring启动部分(有相应的文章介绍)。 本文不会对各个流程做展开分析&#xff0c;后续会有文章介绍详细流程。 SpringApplication类 应用启动入口 使用以下方式启动一个SpringBoot应用&#xff1a; S…

【计算机视觉】最近跑实验的感悟:大模型训练太难了!

文章目录 一、大模型训练太难了二、大模型的训练有三大难点三、OpenAI 的一些启发 一、大模型训练太难了 这里大模型训练特指基座大模型的从0开始训练&#xff0c;不包括在2000条数据上SFT这样的小任务。 有人说大模型嘛&#xff0c;简单&#xff0c;给我卡就行&#xff0c;等…

「2023」高频前端面试题汇总之JavaScript篇(上)

近期整理了一下高频的前端面试题&#xff0c;分享给大家一起来学习。如有问题&#xff0c;欢迎指正&#xff01; 一、数据类型 1. JavaScript有哪些数据类型&#xff0c;它们的区别&#xff1f; JavaScript共有八种数据类型&#xff0c;分别是 Undefined、Null、Boolean、N…

【JVM系列】内存分配与回收策略详解

文章目录 Minor GC 和 Full GC内存分配策略一般过程第一次轻GC第二次轻GC第N次GC 特殊过程小结 Full GC 的触发条件1. 调用 System.gc()2. 老年代空间不足3. 空间分配担保失败4. JDK 1.7 及以前的永久代空间不足5. Concurrent Mode Failure Minor GC 和 Full GC Minor GC&#…

基于DDD实现的用户注册流程,很优雅!

欢迎回来&#xff0c;我是飘渺。今天继续更新DDD&微服务的系列文章。 在前面的文章中&#xff0c;我们深入探讨了DDD的核心概念。我理解&#xff0c;对于初次接触这些概念的你来说&#xff0c;可能难以一次性完全记住。但别担心&#xff0c;学习DDD并不仅仅是理论的理解&am…

6.SpringCloudAlibaba 整合 Sentinel

一、分布式系统遇到的问题 1 服务雪崩效应 在分布式系统中&#xff0c;由于网络原因或自身的原因&#xff0c;服务一般无法保证 100%是可用的。如果一个服务出现了问题&#xff0c;调用这个服务就会出现线程阻塞的情况&#xff0c;此时若有大量的请求涌入&#xff0c;就会出现…