【线程池】ThreadPoolExecutor的使用示例

文章目录

    • 通过ThreadPoolExecutor创建线程池。
    • 线程的处理结果如何获取?

通过ThreadPoolExecutor创建线程池。

ThreadPoolExecutor构造方法参数:

  • int corePoolSize //核心线程数量
  • int maximumPoolSize//最大线程数
  • long keepAliveTime//当线程数大于核心线程数时,多余空闲线程存活的最长时间
  • TimeUnit unit//keepAliveTime的时间单位
  • BlockingQueue<Runnable> workQueue//任务队列,用来储存等待执行任务的队列
  • ThreadFactory threadFactory//用来创建线程的线程工厂,一般默认
  • RejectedExecutionHandler handler//拒绝策略,当提交的任务过多而不能及时处理时所执行的处理策略

演示使用ThreadPoolExecutor执行任务


import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class TestThreadPool {
    public static void main(String[] args) {
        // 创建一个线程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                5,  // 核心线程数
                5,  // 最大线程数
                2,  // 当线程数大于核心线程数时,多余的空闲线程存活的最长时间
                TimeUnit.SECONDS,  // 存活时间单位
                new LinkedBlockingQueue<>(10)  // 任务队列,用来储存等待执行任务的队列
        );

        // 提交任务给线程池
        for (int i = 0; i < 10; i++) {
            final int taskId = i;
            executor.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("Task " + taskId + " is being executed by " + Thread.currentThread().getName());
                    try {
                        Thread.sleep(1000); // 模拟任务执行时间
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("Task " + taskId + " is completed");
                }
            });
        }

        // 关闭线程池
        executor.shutdown();
    }
}

在这个示例中,使用 ThreadPoolExecutor 创建了一个线程池,提交了 10 个任务给线程池,线程池会根据核心线程数和任务队列的情况来分配线程执行任务。任务执行完毕后,线程池会复用线程,如果线程池中的线程数量超过核心线程数,空闲线程在空闲时间后可能会被回收。

最后,调用 shutdown 方法关闭线程池,等待所有任务完成后关闭。

代码运行:
在这里插入图片描述

上述代码中的,提交任务给线程池时所调用的submit也可更改为execute方法。

execute 适用于只关心任务的执行,不需要获取返回值或处理异常的情况;submit 适用于需要获取任务的执行结果或捕获异常的情况。

ThreadPoolExecutor类:
在这里插入图片描述
AbstractExecutorService抽象类(ThreadPoolExecutor的父类):
在这里插入图片描述

线程的处理结果如何获取?

代码:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

public class TestThreadPool2 {
    public static void main(String[] args) {
        // 创建一个线程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                5,  // 核心线程数
                5,  // 最大线程数
                2,  // 当线程数大于核心线程数时,多余的空闲线程存活的最长时间
                TimeUnit.SECONDS,  // 存活时间单位
                new LinkedBlockingQueue<>(10)  // 任务队列,用来储存等待执行任务的队列
        );
        List<Future<Integer>> futureList = new ArrayList<>();
        // 提交任务给线程池
        for (int i = 0; i < 6; i++) {
            final int taskId = i;
            Future<Integer> future = executor.submit(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    System.out.println("Task " + taskId + " is being executed by " + Thread.currentThread().getName());
                    Thread.sleep(2000); // 模拟任务执行时间
                    return taskId * 2;

                }
            });
            futureList.add(future);

        }
        System.out.println("———————flag1———————————");
        // 获取线程的返回值
        for (Future<Integer> future : futureList) {
            try {
                int result = future.get();//get方法会阻塞,直到任务完成并返回结果
                System.out.println("Task result: " + result);
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }
        System.out.println("———————flag2———————————");

        // 关闭线程池
        executor.shutdown();
    }
}

该示例代码创建了一个自定义的 ThreadPoolExecutor,并提交了一系列的 Callable 任务。每个任务都会返回一个整数值。我们将每个任务的 Future 对象存储在一个列表中,然后使用 get 方法获取每个任务的返回值。注意,get 方法会阻塞,直到任务完成并返回结果。

输出:
在这里插入图片描述

参考:

  • https://pdai.tech/md/java/thread/java-thread-x-juc-executor-ThreadPoolExecutor.html#threadpoolexecutor%E6%BA%90%E7%A0%81%E8%AF%A6%E8%A7%A3
  • https://javaguide.cn/java/concurrent/java-concurrent-questions-03.html#%E7%BA%BF%E7%A8%8B%E6%B1%A0

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

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

相关文章

drools8尝试(加单元测试)

drools8的maven模板项目里没有单元测试, 相比而言drools7有个非常好的test senorios 那就自己弄一个 文件是.http后缀的,写了个简单的例子如下 //测试交通违章 POST http://localhost:8080/Traffic Violation accept: application/json Content-Type: application/json{&q…

STM32--SPI通信与W25Q64(1)

文章目录 前言SPI通信硬件电路移位过程 SPI时序起始与终止条件交换一个字节 W25Q64硬件电路框图 FLASH操作注意事项软件SPI读写W25Q64 前言 USART串口链接入口 I2C通信链接入口 SPI通信 SPI&#xff08;Serial Peripheral Interface&#xff09;是一种高速的、全双工、同步的串…

Java中HashMap的基本介绍和详细讲解,HashMap的遍历以及HashMap的底层源码的分析

HashMap 基本介绍 HashMap 是 Java 中的一个集合类&#xff0c;实现了 Map 接口&#xff0c;用于存储键值对&#xff08;key-value&#xff09;数据。它基于哈希表的数据结构实现&#xff0c;可以实现高效的查找、插入和删除操作。 HashMap 细节讨论 无序性&#xff1a; Has…

Python高光谱遥感数据处理与高光谱遥感机器学习方法应用

本文提供一套基于Python编程工具的高光谱数据处理方法和应用案例。 本文涵盖高光谱遥感的基础、方法和实践。基础篇以学员为中心&#xff0c;用通俗易懂的语言解释高光谱的基本概念和理论&#xff0c;旨在帮助学员深入理解科学原理。方法篇结合Python编程工具&#xff0c;专注…

【C++】list

list 1. 简单了解list2. list的常见接口3. 简单实现list4. vector和list比较 1. 简单了解list list的底层是带头双向循环列表。因此list支持任意位置的插入和删除&#xff0c;且效率较高。但其缺陷也很明显&#xff0c;由于各节点在物理空间是不连续的&#xff0c;所以不支持对…

thinkphp安装workman

需要加版本&#xff0c;版本太高了不行 composer require topthink/think-worker1.0.*

Github的使用指南

首次创建仓库 1.官网创建仓库 打开giuhub官网&#xff0c;右上角点击你的头像&#xff0c;随后点击your repositories 点击New开始创建仓库 如下图为创建仓库的选项解释 出现如下界面就可以进行后续的git指令操作了 2.git上传项目 进入需上传项目的所在目录&#xff0c;打开…

keepalived+haproxy 搭建高可用高负载高性能rabbitmq集群

一、环境准备 1. 我这里准备了三台centos7 虚拟机 主机名主机地址软件node-01192.168.157.133rabbitmq、erlang、haproxy、keepalivednode-02192.168.157.134rabbitmq、erlang、haproxy、keepalivednode-03192.168.157.135rabbitmq、erlang 2. 关闭三台机器的防火墙 # 关闭…

自动控制原理笔记-采样控制系统

目录 采样控制系统的基本概念&#xff1a; 采样过程及采样定理&#xff1a; 一、采样过程 二、采样定理&#xff08;香农采样定理、奈奎斯特采样定律&#xff09; 三、信号复现 四、零阶保持器 z变换与z反变换&#xff1a; z变换的定义 z变换基本定理 z反变换 采样系…

gorm中正确的使用json数据类型

一、说明 1、JSON 数据类型是 MySQL 5.7.8 开始支持的。在此之前&#xff0c;只能通过字符类型&#xff08;CHAR&#xff0c;VARCHAR 或 TEXT &#xff09;来保存 JSON 文档。现实中也很多人不会采用json的存储方式&#xff0c;直接定义一个字符类型,让前端转换传递进来,返回给…

HTTPS协议加密原理

目录 一、什么是HTTPS 二、什么是加密/解密 三、为什么要加密 四、常见的加密方式 1.对称加密 2. 非对称加密 五、HTTPS加密方式探讨 1.只使用对称加密 2.只使用非对称加密 3.非对称加密对称加密 4.非对称加密对称加密CA认证 六、总结 一、什么是HTTPS HTTP 协议&a…

vue3+element下拉多选框组件

<!-- 下拉多选 --> <template><div class"select-checked"><el-select v-model"selected" :class"{ all: optionsAll, hidden: selectedOptions.data.length < 2 }" multipleplaceholder"请选择" :popper-app…

git及GitHub的使用

文章目录 git在本地仓库的使用github使用创建仓库https协议连接(不推荐&#xff0c;现在用起来比较麻烦)ssh连接&#xff08;推荐&#xff09;git分支操作冲突处理忽略文件 git在本地仓库的使用 1.在目标目录下右键打开git bash here 2.创建用户名和邮箱(注&#xff1a; 下载完…

ms-tpm-20-ref 在linux下编译

1、代码地址&#xff0c; GitHub - microsoft/ms-tpm-20-ref: Reference implementation of the TCG Trusted Platform Module 2.0 specification.Reference implementation of the TCG Trusted Platform Module 2.0 specification. - GitHub - microsoft/ms-tpm-20-ref: Refe…

Nodejs-nrm:快速切换npm源 / npm官方源和其他自定义源之间切换

一、理解 Nodejs nrm Nodejs nrm 是一个管理 npm 源的工具。由于 npm 在国内的速度较慢&#xff0c;很多开发者会使用淘宝的 npm 镜像源&#xff0c;但是也会遇到一些问题&#xff0c;例如某些包在淘宝镜像源中不存在&#xff0c;或者淘宝镜像源本身也会有问题。 Nodejs nrm …

CSS scoped 属性的原理

scoped 一、scoped 是什么&#xff1f;二、实现原理 一、scoped 是什么&#xff1f; 在 Vue 组件中&#xff0c;为了使样式私有化&#xff08;模块化&#xff09;&#xff0c;不对全局造成污染&#xff0c;可以在 style 标签上添加 scoped 属性以表示它的只属于当下的模块&am…

【MOS管的作用和工作原理】

数电/模电知识学习与分享001 MOS管的作用和工作原理1、MOS管基本概念2、MOS管基本原理3、MOS管广泛作用4、MOS管特点4、参考文献 MOS管的作用和工作原理 1、MOS管基本概念 MOS管&#xff08;Metal-Oxide-Semiconductor Field-Effect Transistor&#xff09;是一种常用的半导体…

Unity 之利用 localEulerAngle与EulerAngle 控制物体旋转

文章目录 概念讲解localEulerAngle与EulerAngle的区别 概念讲解 欧拉角&#xff08;Euler Angles&#xff09;是一种常用于描述物体在三维空间中旋转的方法。它使用三个角度来表示旋转&#xff0c;分别绕物体的三个坐标轴&#xff08;通常是X、Y和Z轴&#xff09;进行旋转。这…

AI Agent在情景猜谜场景下的AgentBench基准测试

目录 AgentBench评估哪些场景? 近日,来自清华大学、俄亥俄州立大学和加州大学伯克利分校的研究者设计了一个测试工具——AgentBench,用于评估LLM在多维度开放式生成环境中的推理能力和决策能力。研究者对25个LLM进行了全面评估,包括基于API的商业模型和开源模型。 他们发现…

安卓移动应用开发实训室建设方案

一 、系统概述 安卓移动应用开发作为新一代信息技术的重点和促进信息消费的核心产业&#xff0c;已成为我国转变信息服务业的发展新热点&#xff1a;成为信息通信领域发展最快、市场潜力最大的业务领域。互联网尤其是移动互联网&#xff0c;以其巨大的信息交换能力和快速渗透能…