Java线程池—附阿里巴巴Java开发手册强制规范要求

文章目录

    • 一、线程池概述
    • 二、创建线程池
    • 三、线程池执行Runnable任务
    • 四、线程池执行Callable任务
    • 五、线程池工具类(Executors)—不推荐

一、线程池概述

线程池就是一个可以复用线程的技术
想象一下,如果不使用线程池会有什么问题?

假设:用户每次发起一个请求给后台,后台就创建一个新的线程来处理,下次新的任务过来肯定也会创建新的线程,如果用户量非常大,创建的线程也讲越来越多。然而,创建线程是开销很大的,并且请求过多时,会严重影响系统性能。

而使用线程池,就可以解决上面的问题。如下图所示,线程池内部会有一个容器,存储几个核心线程,假设有3个核心线程,这3个核心线程可以处理3个任务。

在这里插入图片描述

但是任务总有被执行完的时候,假设第1个线程的任务执行完了,那么第1个线程就空闲下来了,有新的任务时,空闲下来的第1个线程可以去执行其他任务。依此内推,这3个线程可以不断的复用,也可以执行很多个任务。
在这里插入图片描述
所以,线程池就是一个线程复用技术,它可以提高线程的利用率。

二、创建线程池

在JDK5版本中提供了代表线程池的接口ExecutorService,而这个接口下有一个实现类叫ThreadPoolExecutor类,使用ThreadPoolExecutor类就可以用来创建线程池对象。
下面是它的构造器如图所示:
在这里插入图片描述

常见的代码演示如下所示:

ExecutorService pool = new ThreadPoolExecutor(
    3,	//核心线程数有3个
    5,  //最大线程数有5个。   临时线程数=最大线程数-核心线程数=5-3=2
    8,	//临时线程存活的时间8秒。 意思是临时线程8秒没有任务执行,就会被销毁掉。
    TimeUnit.SECONDS,//时间单位(秒)
    new ArrayBlockingQueue<>(4), //任务阻塞队列,没有来得及执行的任务在,任务队列中等待
    Executors.defaultThreadFactory(), //用于创建线程的工厂对象
    new ThreadPoolExecutor.CallerRunsPolicy() //拒绝策略
);

关于线程池,需要注意下面的两个问题:

  • 临时线程什么时候创建?
    新任务提交时,发现核心线程都在忙、任务队列满了、并且还可以创建临时线程,此时会创建临时线程。
  • 什么时候开始拒绝新的任务?
    核心线程和临时线程都在忙、任务队列也满了、新任务过来时才会开始拒绝任务。

三、线程池执行Runnable任务

线程池执行的任务可以有两种,一种是Runnable任务;一种是callable任务。下面的execute方法可以用来执行Runnable任务。
在这里插入图片描述
先准备一个线程任务类

public class MyRunnable implements Runnable{
    @Override
    public void run() {
        // 任务是干啥的?
        System.out.println(Thread.currentThread().getName() + " ==> 输出666~~");
        //为了模拟线程一直在执行,这里睡久一点
        try {
            Thread.sleep(Integer.MAX_VALUE);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

下面是执行Runnable任务的代码

ExecutorService pool = new ThreadPoolExecutor(
    3,	//核心线程数有3个
    5,  //最大线程数有5个。   临时线程数=最大线程数-核心线程数=5-3=2
    8,	//临时线程存活的时间8秒。 意思是临时线程8秒没有任务执行,就会被销毁掉。
    TimeUnit.SECONDS,//时间单位(秒)
    new ArrayBlockingQueue<>(4), //任务阻塞队列,没有来得及执行的任务在,任务队列中等待
    Executors.defaultThreadFactory(), //用于创建线程的工厂对象
    new ThreadPoolExecutor.CallerRunsPolicy() //拒绝策略
);

Runnable target = new MyRunnable();
pool.execute(target); // 线程池会自动创建一个新线程,自动处理这个任务,自动执行的!
pool.execute(target); // 线程池会自动创建一个新线程,自动处理这个任务,自动执行的!
pool.execute(target); // 线程池会自动创建一个新线程,自动处理这个任务,自动执行的!
//下面4个任务在任务队列里排队
pool.execute(target);
pool.execute(target);
pool.execute(target);
pool.execute(target);

//下面2个任务,会被临时线程的创建时机了
pool.execute(target);
pool.execute(target);
// 到了新任务的拒绝时机了!
pool.execute(target);

在这里插入图片描述

四、线程池执行Callable任务

callable任务相对于Runnable任务来说,就是多了一个返回值。执行Callable任务需要用到下面的submit方法
在这里插入图片描述
先准备一个Callable线程任务

public class MyCallable implements Callable<String> {
    private int n;
    public MyCallable(int n) {
        this.n = n;
    }

    // 2、重写call方法
    @Override
    public String call() throws Exception {
        // 描述线程的任务,返回线程执行返回后的结果。
        // 需求:求1-n的和返回。
        int sum = 0;
        for (int i = 1; i <= n; i++) {
            sum += i;
        }
        return Thread.currentThread().getName() + "求出了1-" + n + "的和是:" + sum;
    }
}

再准备一个测试类,在测试类中创建线程池,并执行callable任务。

public class ThreadPoolTest2 {
    public static void main(String[] args) throws Exception {
        // 1、通过ThreadPoolExecutor创建一个线程池对象。
        ExecutorService pool = new ThreadPoolExecutor(
            3,
            5,
            8,
            TimeUnit.SECONDS, 
            new ArrayBlockingQueue<>(4),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.CallerRunsPolicy());

        // 2、使用线程处理Callable任务。
        Future<String> f1 = pool.submit(new MyCallable(100));
        Future<String> f2 = pool.submit(new MyCallable(200));
        Future<String> f3 = pool.submit(new MyCallable(300));
        Future<String> f4 = pool.submit(new MyCallable(400));

        // 3、执行完Callable任务后,需要获取返回结果。
        System.out.println(f1.get());
        System.out.println(f2.get());
        System.out.println(f3.get());
        System.out.println(f4.get());
    }
}

五、线程池工具类(Executors)—不推荐

Java为开发者提供了一个创建线程池的工具类,叫做Executors,它提供了方法可以创建各种不能特点的线程池。如下图所示:
在这里插入图片描述
示例demo如下:

public class ThreadPoolTest3 {
    public static void main(String[] args) throws Exception {
        // 1、通过Executors创建一个线程池对象。
        ExecutorService pool = Executors.newFixedThreadPool(17);
        // 老师:核心线程数量到底配置多少呢???
        // 计算密集型的任务:核心线程数量 = CPU的核数 + 1
        // IO密集型的任务:核心线程数量 = CPU核数 * 2

        // 2、使用线程处理Callable任务。
        Future<String> f1 = pool.submit(new MyCallable(100));
        Future<String> f2 = pool.submit(new MyCallable(200));
        Future<String> f3 = pool.submit(new MyCallable(300));
        Future<String> f4 = pool.submit(new MyCallable(400));

        System.out.println(f1.get());
        System.out.println(f2.get());
        System.out.println(f3.get());
        System.out.println(f4.get());
    }
}

Executors创建线程池这么好用,但是不推荐使用,为什么呢?原因在这里:看下图,这是《阿里巴巴Java开发手册》提供的强制规范要求。
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

spring IOC介绍

spring的Ioc真是个好东西啊&#xff0c;那它到底是什么东西呢&#xff0c;控制反转&#xff0c;到底是怎么转的呢&#xff1f; 假设啊你现在是一个导演&#xff0c;想排部戏&#xff0c;那是不是得需要演员和舞台(spring中的bean)&#xff0c;如果按平常的编程思维就是new 一个…

女装品牌网站建设的作用如何

服装是任何人都需要的必备品&#xff0c;尤其是女装&#xff0c;由于女性群体爱美追求时尚的心理更高&#xff0c;因此市场中有大量女装品牌以及大量消费者&#xff0c;其规模非常高&#xff0c;众多大小品牌林立及消费征集下&#xff0c;商家们经营也并不太容易&#xff0c;企…

YouTube网红营销:出海品牌扩大影响力的关键

随着数字媒体的兴起&#xff0c;社交媒体已成为品牌与消费者之间建立联系的重要桥梁。其中&#xff0c;YouTube作为全球最大的视频分享平台&#xff0c;不仅拥有庞大的用户群体&#xff0c;还聚集了众多有影响力的网红。这些网红在各自的领域内拥有强大的话语权和号召力&#x…

区块链实验室(28) - 拜占庭节点劫持区块链仿真

在以前的FISCO环境中仿真拜占庭节点攻击区块链网络。该环境共有100个节点&#xff0c;采用PBFT作为共识机制&#xff0c;节点编号分别为&#xff1a;Node0&#xff0c;Node&#xff0c;… &#xff0c;Node99。这100个节点的前2010区块完全相同&#xff0c;自区块2011开始分叉。…

No suitable driver found for jdbc:mysql://localhost:3306(2023/12/7更新)

有两种情况&#xff1a; 压根没安装下载了但没设为库或方法不对 大多数为第一种情况&#xff1a; 一. 下载jdbc 打开网址选择一个版本进行下载 https://nowjava.com/jar/version/mysql/mysql-connector-java.html 二.安装jdbc 在项目里建一个lib文件夹 在把之前下载的jar文…

【开源】基于Vue+SpringBoot的陕西非物质文化遗产网站

文末获取源码&#xff0c;项目编号&#xff1a; S 065 。 \color{red}{文末获取源码&#xff0c;项目编号&#xff1a;S065。} 文末获取源码&#xff0c;项目编号&#xff1a;S065。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 设计目标2.2 研究内容2.3 研究方法与…

四十一、高可用

一、定义 TC&#xff08;Tencent Cloud&#xff09;的异地多机房容灾架构是指&#xff0c;在不同的地理位置上配置多个数据中心&#xff0c;以确保系统的高可用性和容灾能力。当某个数据中心发生故障或者不可用时&#xff0c;可以自动切换到其他数据中心来提供服务&#xff0c;…

vscode如何为python设置静态类型检测工具:mypy

设置好之后的效果如下图所示&#xff0c;你可以在下方problems一栏看到工作区所有文件存在的问题 安装mypy就像其他插件一样&#xff0c;在extensions中搜索mypy&#xff0c;再install即可。 但是安装以后&#xff0c;我的vscode弹出了以下通知&#xff1a; The mypy daemon e…

Global IIIumination(GI)全局光照原理(一)3D空间全局光照

文章目录 一、Global IIIumination&#xff08;GI&#xff09;全局光照基本概念二、主流的全局光照方法&#xff1a;三、Reflective shadow maps&#xff08;RSM&#xff09;反射阴影贴图 全局光照四、Light Propagation Volumes (LPV)光线传播体积 全局光照1.第一步&#xff0…

Linux中的网络时间服务器

本章主要介绍网络时间的服务器 使用chrony配置时间服务器配置chrony客户端服务器同步时间 1.1 时间同步的重要性 一些服务对时间要求非常严格&#xff0c;例如如图所示的由三台服务器搭建的ceph集群 这三台服务器的时间必须保持一致&#xff0c;如果不一致&#xff0c;就会显…

C语言之动态内存管理(malloc calloc realloc)

C语言之动态内存管理 文章目录 C语言之动态内存管理1. 为什么要有动态内存管理2. malloc 和 free2.1 malloc2.2 free2.3 例子 3. calloc 和 realloc3.1 calloc3.2 realloc 4. 常见的动态内存错误4.1 对NULL指针的解引⽤操作4.2 对动态开辟空间的越界访问4.3 对⾮动态开辟内存使…

Themis: Fast, Strong Order-Fairness in Byzantine Consensus

目录 笔记后续的研究方向摘要引言秩序井然 Themis: Fast, Strong Order-Fairness in Byzantine Consensus CCS 2023 笔记 后续的研究方向 摘要 我们介绍了Themis&#xff0c;这是一种将交易的公平排序引入&#xff08;许可的&#xff09;拜占庭共识协议的方案&#xff0c;最…

【洛谷】更换头像

错误展示 今天换头像的时候发现一直换不了&#xff0c;即使显示修改成功&#xff0c;然后我等了半个多小时也还没换好 解决办法 上传成功头像后&#xff0c;按ctrl F5 结果 更新成功&#xff01;

文本润色工具有哪些,高质量的文本润色软件

在当今信息过载的时代&#xff0c;文本的重要性愈发凸显。即便是最精心构思的文章&#xff0c;若未经过仔细的润色&#xff0c;也难以达到最佳的表达效果。本文将专心分享文本润色工具的种类。 文本润色工具的种类 文本润色工具根据其功能和应用范围可以分为多个种类&#xff…

菜鸟学习日记(python)——推导式

python中的推导式是一种独特的数据处理方式&#xff0c;可以从一个数据序列去构建另一个新的数据序列的结构体。 它包括以下推导式&#xff1a; 列表&#xff08;list&#xff09;推导式字典&#xff08;dict&#xff09;推导式集合&#xff08;set&#xff09;推导式元组&am…

Kettle 安装配置

文章目录 Kettle 安装配置Kettle 安装Kettle 配置连接 Hive Kettle 安装配置 Kettle 安装 在安装Kettle之前&#xff0c;需要确定已经安装Java运行环境。Kettle需要Java的支持才能运行&#xff0c;JDK的版本最好是8.x的太新的也会出现bug。Kettle的7.1版本的太旧了&#xff0…

排序-插入排序与希尔排序

文章目录 一、插入排序二、希尔排序 一、插入排序 思路&#xff1a; 当插入第i(i>1)个元素时&#xff0c;前面的array[0],array[1],…,array[i-1]已经排好序&#xff0c;此时用array[i]的排序码与array[i-1],array[i-2],…的排序码顺序进行比较&#xff0c;找到插入位置即将…

Apollo新版本Beta自动驾驶技术沙龙参会体验有感—百度自动驾驶开源框架

在繁忙的都市生活中&#xff0c;我们时常对未来的科技发展充满了好奇和期待。而近日&#xff0c;我有幸参加了一场引领科技潮流的线下技术沙龙&#xff0c;主题便是探索自动驾驶的魅力——一个让我们身临其境感受创新、了解技术巨擘的机会。 在12月2日我有幸参加了Apollo新版本…

PaddleClas学习3——使用PPLCNet模型对车辆朝向进行识别(c++)

使用PPLCNet模型对车辆朝向进行识别 1 准备环境2 准备模型2.1 模型导出2.2 修改配置文件3 编译3.1 使用CMake生成项目文件3.2 编译3.3 执行3.4 添加后处理程序3.4.1 postprocess.h3.4.2 postprocess.cpp3.4.3 在cls.h中添加函数声明3.4.4 在cls.cpp中添加函数定义3.4.5 在main.…

亚马逊、OZON、速卖通、美客多店铺怎么增加页面访问量?

店铺怎么增加页面访问量&#xff1f;页面访问量是衡量你的亚马逊店铺或产品在互联网上的可见性和曝光度的重要指标。如果你的店铺没有足够的访问量&#xff0c;意味着很少有人能看到你的内容或产品&#xff0c;这将限制你的潜在受众和销售机会。 没有流量就没有店铺&#xff0c…
最新文章