[多线程]线程池

news2024/9/25 23:22:04

目录

1.前言

2. Java中的线程池以及参数介绍

2.1 核心线程数和最大线程数

2.2最大空闲存活时间

2.3任务队列和线程工厂

2.4 拒绝策略(最重要)

2.5 线程池的类型

3.线程池的大小如何确定

4.手动写一个线程池


1.前言

    我们知道.在开发过程中.为了效率,会引进很多池,比如常量池,对象池,字符串池.今天我们来介绍另一种可以管理线程的池,线程池.我们知道在多线程编程中,线程的开销是比较大的,如线程的摧毁和创建.为了解决这种问题,我们引入了线程池这个概念,它可以把部分线程的创建和销毁给省去了,而是直接放到特定的数据结构里,需要用的时候再拿出来.这样就可以极大的提升程序的效率

2. Java中的线程池以及参数介绍

  在Java中,也为我们封装了线程池的类,ThreadpollExecutor类,而这个类里面有几个重要的参数。它的构造方法有四种。             

    我们这里来重点介绍一下第四个构造方法,因为这个构造方法里的参数是最完整的。它包含了前面几个构造方法里的参数。

2.1 核心线程数和最大线程数

int  corePoolSize  核心线程数,相当于是正式的线程,正式工。

int maxmumPoolSize 最大线程数,除了核心线程,还有临时线程,相当于临时工,实习生。

2.2最大空闲存活时间

long keepAliveTime 实习生线程允许的最大空闲存活时间。 就是除了核心线程数之外的线程,在没有被利用到的时候,可以存在的时间。

TimeUnit unit 最大空闲存活时间单位,(s,hour,day。。。)

2.3任务队列和线程工厂

BlockkingQueue<Runable> workQueue 线程池里的任务队列,它是一个阻塞队列。

Threadfactry threadFactory 线程工厂

工厂模式可以解决Java语法的缺陷,就是在重载的时候,参数不能相同,但实际上,我们会有这种业务需求。比如,我们需要通过构造方法,来创建类,但是我们想传入的形参它的意义不同,但是类型和个数都一样。在Java基本语法中,是做不到的。但是我们可以通过把构造方法进行封装, 把它们放到工厂类里面去,通过工厂类来进行创建对象。

2.4 拒绝策略(最重要)

RejectedExecutionHandler  handler

  线程池中,会有一个阻塞队列。所以它能容纳的线程数量是有限的,当任务队列里的线程数满了以后,线程池会做出什么样的举动。这个是可以我们来控制一下的,所以就引入了 我们的拒绝策略。

在标准库里,Java为我们提供了四种拒绝策略。

我们来逐个解释一下这些拒绝策略分别是什么:
 

ThreadPoolExecutor.AbortPolicy  

   抛出一个 RejectedExecutionException ,举个例子,就好比我现在在家做家务,手头有好几个活,我妈这时候让我在做一个新的家务,如果是这种拒绝策略。那就是我情绪崩溃了,哇的一声就哭出来了,然后撂挑子不干了。

ThreadPoolExecutor.CallerRunsPolicy  

新的任务,由添加任务的线程去执行。也就是我上述例子中,我给我妈说,我不干,你去做。

ThreadPoolExecutor.DiscardOldestPolicy 
被拒绝的任务的处理程序,丢弃最旧的未处理请求。就是把队列中,最老的那个线程给丢掉,然后加入这个最新的。就是上述例子中,我有一个最早的家务,比如是拖地,我就不去做这个了,而是把新家务给放到我的家务计划中。

ThreadPoolExecutor.DiscardPolicy 

直接丢掉最新的,不要别的线程加入,加不进去。就是我直接拒绝了给我安排的家务,并不会出现在我的家务计划列表中。

2.5 线程池的类型

Java标准库中,有这么四类线程池的类型。我们来通过图片来给大家看看。

   如果只是简单用一下,就用这几种就可以了。如果需要高度定制化,那么就需ThreadPoolExecutor。来逐个设置参数了。阿里巴巴编程规范,要我们使用ThreadPoolExecutor。来让线程池更可控。可以参考一下。大家要以实际开发入职的编程规范为准。

3.线程池的大小如何确定

   网上有很多种关于线程池大小如何设定的说法,有的说如果cpu逻辑核心数是N,那么就应该设置为N个,1.5N.2N...但是这些说法都不严谨。

我们要看具体的代码里,线程中是cpu密集型的操作,还是io密集型的操作。如果是cpu密集型的操作,那么就设置为N就行,如果是io密集型的操作,这个时候对于cpu的消耗就比较小,我们就可以设置为远大于N的线程池大小。

但是在具体的工作开发中,这个东西是很难通过看代码来确定的,因为任务会很复杂,大概率是cpu和io同时都有,所以综上所述,最好的方法就是通过实验来确定。设置多大的合适,对于性能的提升最大。

实践是检验真理的唯一标准!

4.手动写一个线程池

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.BlockingQueue;

 class MyThreadPoolExcutor {
    private BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(1000);
    private List<Thread> list = new ArrayList<>();

    public MyThreadPoolExcutor(int a){

        for (int i = 0; i < a; i++) {
            Thread t =new Thread(()->{
                while (true){
                    try {
                       Runnable runnable =queue.take();
                       runnable.run();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }

            });
            t.start();
            list.add(t);
        }
    }
    public void submit(Runnable runnable) throws InterruptedException {
        queue.put(runnable);
    }
}
public class MyThreadExcutor {
    public static void main(String[] args) throws InterruptedException {
        MyThreadPoolExcutor myThreadPoolExcutor = new MyThreadPoolExcutor(4);
        for (int i =0; i < 1000; i++) {
            int a= i;
            myThreadPoolExcutor.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("打印变量" + a +"执行的线程为" + Thread.currentThread().getName());
                }
            });
        }


    }
}

在上述代码里,我们手动创建了一个线程池,是固定线程的线程池。里面有一个带阻塞功能的任务队列,当我们put进去新的任务的时候,会进入到任务队列中。然后线程池里的线程就会执行这个任务,至于是哪个线程,是随机的一个。

这段代码实现了一个简单的线程池,能够并发执行多个任务,而不需要为每个任务都创建一个新的线程。

                                                                                                                                                  

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

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

相关文章

激荡思享 驱动增长 | 湾数联·湾董会走进竹云

12月12日&#xff0c;由湾区数字科技产业联盟&#xff08;GBADA&#xff09;、湾盟产业创新服务中心&#xff08;GBAIC&#xff09;、深圳竹云科技股份有限公司联合主办的“湾数联湾董会”第一期在深圳南山区创智云城圆满举办。本期湾董会以“竹云IDaaS数字身份为企业数字化转型…

Amazon CodeWhisperer:AI 编程助手

文章作者&#xff1a;prigioni 1. 什么是 Amazon CodeWhisperer&#xff1f; Amazon CodeWhisperer 能够理解以自然语言&#xff08;英语&#xff09;编写的注释&#xff0c;并能实时生成多条代码建议&#xff0c;以此提高开发人员生产力。该服务可以直接在集成开发环境&#…

HTTP 301错误:永久重定向,大勇的冒险之旅

大家好&#xff0c;我是大勇&#xff0c;一个喜欢冒险的程序员。今天&#xff0c;我要和大家分享一个我在互联网世界中的冒险故事——如何处理HTTP 301错误&#xff1a;永久重定向。 那天&#xff0c;我像往常一样&#xff0c;打开我的代码编辑器&#xff0c;准备开始一天的工…

Java刷题篇——LeetCode118. 杨辉三角

1.题目描述 给定一个非负整数numRows&#xff0c;生成杨辉三角的前numRows行。 在杨辉三角中&#xff0c;每个数是它左上方和右上方的数的和。 示例1 输入&#xff1a;numRows 5 输出&#xff1a;[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1] 示例2 输入&#xff1a;numRows 1…

搜维尔科技:第九届元宇宙数字人设计大赛校园行讲演活动正式启动—中国戏曲学院站!

由全国高等院校计算机基础教育研究会指导&#xff0c;利亚德集团和爱迪斯通科技发起的数字人设计大赛正在火热进行中&#xff0c;同时进行的元宇宙数字人设计大赛校园行活动也正式拉开序幕&#xff0c;12月13日校园行活动—中国戏曲学院开讲。划重点&#xff1a;此次大赛已成为…

高性能国产TYPE-C/DP/EDP转MIPIDSI/CSI/LVDS,龙迅LT7911D,支持高达4K60HZ的分辨率

LT7911D概述&#xff1a; T7911D是一款高性能TYPE-C/DP/EDP转2 PORT MIPI或者LVDS的芯片&#xff0c;目前主要在AR/VR或者显示器上应用的很多&#xff0c;对于DP1.2输入&#xff0c;LT7911D可配置为1/2/4车道。自适应均衡化使其适用于长电缆应用&#xff0c;最大带宽可达21.6G…

ActiveMQ使用指南

介绍 ActiveMQ是Apache开源组织旗下的一个项目&#xff0c;是一个流行的开源消息中间件。它完全支持JMS1.1和J2EE1.4规范的JMS Provider实现&#xff0c;并且是纯Java开发的产品。ActiveMQ支持多种语言编写客户端&#xff0c;包括C,C,C#,Perl,PHP,Ruby,Ajax等&#xff0c;同时…

zk_dubbo

图灵面试笔记 zk dubbo spi dubbo 文章 dubbo与spring整合之Service、Reference注解处理过程 JAVA备忘录

Flutter:web项目跨域问题解决

前后端解决系列 文章目录 一、Flutter web客户端解决本地环境调试跨域问题二、Flutter web客户端解决线上环境跨域问题 一、Flutter web客户端解决本地环境调试跨域问题 就一句命令【--web-browser-flag "--disable-web-security"】&#xff0c;用来屏蔽浏览器域名请…

在线免费压缩pdf文件

在线免费压缩pdf文件&#xff0c;不用登陆哦&#xff0c; https://www.ilovepdf.com/ https://online2pdf.com/#

第十二章 React 路由配置,路由参数获取

一、专栏介绍 &#x1f436;&#x1f436; 欢迎加入本专栏&#xff01;本专栏将引领您快速上手React&#xff0c;让我们一起放弃放弃的念头&#xff0c;开始学习之旅吧&#xff01;我们将从搭建React项目开始&#xff0c;逐步深入讲解最核心的hooks&#xff0c;以及React路由、…

模型放置到3D场景中后模型位置与鼠标选中的位置不一致怎么办?

在线工具推荐&#xff1a;3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 1、问题 从事3D建模相关工作的朋友们在工作中经常会遇到以下几种问题&#…

网络协议疑点记录

1.RIP, OSPF,BGP 搞清RIP和OSPF的区别,这是我见过最好的总结! - 知乎 首先什么是自治系统:治系统就是几个路由器组成了一个小团体 ?,小团体内部使用专用的协议进行通信,而小团体和小团体之间也使用专用的协议进行通信。 IGP RIP 距离矢量路由算法,bellman-ford算法,…

浏览器js中添加日志断点

一、需求 本地调试时&#xff0c;可以直接代码里使用console.log直接调试&#xff1b; 代码已更新到服务器&#xff0c;不想要提交代码&#xff0c;如何通过添加console.log调试呢 二、实现 使用浏览器添加日志断点的方式&#xff0c;当然vue这种打包的不可行哦 设置完成后…

基于人气与协同过滤的图书推荐系统研究与实践(文末送书)

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

<蓝桥杯软件赛>零基础备赛20周--第10周--二分

报名明年4月蓝桥杯软件赛的同学们&#xff0c;如果你是大一零基础&#xff0c;目前懵懂中&#xff0c;不知该怎么办&#xff0c;可以看看本博客系列&#xff1a;备赛20周合集 20周的完整安排请点击&#xff1a;20周计划 每周发1个博客&#xff0c;共20周&#xff08;读者可以按…

loadrunner脚本--参数化03(ODBC连接测试mysql)

loadrunner脚本–参数化03(ODBC连接测试mysql) 文章目录 loadrunner12.55中&#xff0c;想用ODBC连接mysql数据库进行参数化时&#xff0c;参数列表里面没有data wizard数据向导&#xff0c;而是变成了import paramete&#xff0c;求告知data wizard数据向导去哪里了原因参数数…

win10输入法设置方法,打造高效输入体验

win10作为一款强大的操作系统&#xff0c;注重用户体验的个性化设置。输入法作为我们与电脑互动的桥梁之一&#xff0c;其设置显得尤为重要。本文将深入介绍win10输入法设置的三种方法&#xff0c;让您轻松打造符合个性需求的输入环境。 方法1&#xff1a;通过系统设置更改输入…

安装DevEco Studio

下载 首先进入鸿蒙开发者官网&#xff0c;顶部导航栏选择开发->DevEco Studio 根据操作系统下载不同版本&#xff0c;其中Mac(X86)为英特尔芯片&#xff0c;Mac(ARM)为M芯片。 安装 下载完毕后&#xff0c;开始安装。 点击Agree 首次使用&#xff0c;请选择Do not impor…

Leetcode—2697.字典序最小回文串【简单】

2023每日刷题&#xff08;五十八&#xff09; Leetcode—2697.字典序最小回文串 实现代码 char * makeSmallestPalindrome(char * s){int len strlen(s);int left 0, right len - 1;while(left < len / 2) {if(s[left] > s[right]) {s[left] s[right];} else {s[ri…