线程池:高效管理并发任务的利器

news2024/10/21 5:35:14

线程池:高效管理并发任务的利器


什么是线程池?

线程池(Thread Pool)是Java并发编程中的一种设计模式,旨在通过重复利用线程资源,来提高程序执行效率。线程池的主要思想是提前创建一组可供使用的线程,这些线程在完成任务后并不会销毁,而是返回线程池,等待处理下一个任务。这种方式减少了频繁创建和销毁线程的开销。

线程池能解决的问题:

  • 减少线程创建销毁的开销:频繁创建和销毁线程会影响性能,尤其是在高并发场景下。
  • 控制最大并发量:线程池可以限制同时执行的线程数,避免因创建过多线程导致系统资源耗尽。
  • 线程管理:线程池统一管理线程的生命周期,包括创建、执行、销毁等操作。

如何实现线程池?

在Java中,线程池的实现主要依赖于 java.util.concurrent 包中的 Executor 框架,其中最常用的实现类是 ThreadPoolExecutor

1. 创建线程池

使用 Executors 工具类可以轻松创建常用的线程池,如固定线程池、缓存线程池、单线程池等。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoolExample {
    public static void main(String[] args) {
        // 创建一个固定大小的线程池,线程池大小为3
        ExecutorService threadPool = Executors.newFixedThreadPool(3);
        
        // 提交任务到线程池
        for (int i = 1; i <= 5; i++) {
            final int taskId = i;
            threadPool.submit(() -> {
                System.out.println("Task " + taskId + " is running by thread " + Thread.currentThread().getName());
                try {
                    // 模拟任务耗时
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                System.out.println("Task " + taskId + " completed.");
            });
        }
        
        // 关闭线程池
        threadPool.shutdown();
    }
}
2. 代码解释
  • 创建线程池Executors.newFixedThreadPool(3) 创建了一个包含3个线程的固定线程池。
  • 提交任务:通过 threadPool.submit() 提交任务到线程池,任务被线程池中的线程执行。
  • 模拟任务:每个任务通过 Thread.sleep(1000) 模拟耗时1秒。
  • 关闭线程池shutdown() 方法在所有任务执行完毕后关闭线程池。
3. 运行结果
Task 1 is running by thread pool-1-thread-1
Task 2 is running by thread pool-1-thread-2
Task 3 is running by thread pool-1-thread-3
Task 1 completed.
Task 4 is running by thread pool-1-thread-1
Task 2 completed.
Task 5 is running by thread pool-1-thread-2
Task 3 completed.
Task 4 completed.
Task 5 completed.

解释:最多3个任务可以同时执行,超过的任务需要等待线程池中的线程空闲后才能执行。


如何手动实现线程池?

你也可以通过自己实现一个简单的线程池来了解其原理。下面展示了一个基本的线程池实现。

import java.util.LinkedList;
import java.util.List;

class SimpleThreadPool {
    private final List<Worker> workers; // 存储线程池中的线程
    private final LinkedList<Runnable> taskQueue; // 任务队列
    private volatile boolean isShutdown = false; // 用于标记线程池是否关闭

    public SimpleThreadPool(int poolSize) {
        taskQueue = new LinkedList<>();
        workers = new LinkedList<>();

        for (int i = 0; i < poolSize; i++) {
            Worker worker = new Worker();  // 创建工作线程
            workers.add(worker);
            worker.start();  // 启动线程
        }
    }

    // 提交任务到任务队列
    public synchronized void submit(Runnable task) {
        if (!isShutdown) {
            taskQueue.add(task);
            notify();  // 唤醒等待的工作线程
        }
    }

    // 关闭线程池
    public synchronized void shutdown() {
        isShutdown = true;
        for (Worker worker : workers) {
            worker.interrupt();  // 中断所有工作线程
        }
    }

    private class Worker extends Thread {
        public void run() {
            while (true) {
                Runnable task;
                synchronized (SimpleThreadPool.this) {
                    while (taskQueue.isEmpty() && !isShutdown) {
                        try {
                            SimpleThreadPool.this.wait();  // 等待有新任务到来
                        } catch (InterruptedException e) {
                            return;  // 如果线程被中断,退出
                        }
                    }
                    task = taskQueue.poll();  // 从任务队列中取出任务
                }

                if (task != null) {
                    task.run();  // 执行任务
                }

                if (isShutdown && taskQueue.isEmpty()) {
                    return;  // 如果关闭并且没有任务了,退出线程
                }
            }
        }
    }
}
代码解释
  1. taskQueue:任务队列,用来存储待执行的任务。
  2. Worker:工作线程从任务队列中取任务并执行,空闲时等待新的任务。
  3. submit() 方法:用于提交任务到任务队列,同时通知工作线程执行。
  4. shutdown() 方法:关闭线程池并中断所有工作线程。
    在这里插入图片描述
使用示例
public class CustomThreadPoolDemo {
    public static void main(String[] args) {
        // 创建线程池,大小为3
        SimpleThreadPool pool = new SimpleThreadPool(3);
        
        // 提交任务
        for (int i = 1; i <= 5; i++) {
            final int taskId = i;
            pool.submit(() -> {
                System.out.println("Task " + taskId + " is running by thread " + Thread.currentThread().getName());
                try {
                    Thread.sleep(1000); // 模拟任务耗时
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                System.out.println("Task " + taskId + " completed.");
            });
        }
        
        // 关闭线程池
        pool.shutdown();
    }
}

线程池的使用场景
  1. 高并发系统:在高并发环境下,使用线程池可以避免频繁的线程创建销毁,提高资源利用率。典型的应用如:Web服务器、消息处理系统等。

  2. 任务调度:在定时任务或者需要重复执行的任务场景中,线程池可以高效地管理任务的分发与执行。

  3. 多任务处理:线程池允许多个任务同时运行,并能根据系统资源合理分配线程数量,避免系统过载。


总结

  • 线程池通过复用线程资源来提高并发执行效率,同时可以限制系统中的最大并发线程数,避免资源耗尽。
  • 通过 ExecutorServiceThreadPoolExecutor,Java提供了非常强大的线程池管理机制。
  • 手动实现线程池可以帮助更好地理解线程池的内部工作原理。

线程池的思想可以用于多个并发任务管理场景,比如任务队列处理、大规模请求的负载均衡以及后台任务调度等。

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

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

相关文章

归一化输入

当输入的不同的特征取值范围差异过大&#xff0c;取得对应参数差别也会很大&#xff0c;在对参数进行优化的过程中&#xff0c;参数小的维度步长较小&#xff0c;参数大的维度步长较大&#xff0c;优化过程中路径曲折&#xff0c;将输入归一化&#xff0c;使特征取值范围差别小…

相控阵雷达电特性matlab模拟与仿真,带GUI界面,对比有限扫描阵,稀疏阵,多波束阵,共形阵等

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 相控阵雷达作为一种先进的雷达技术&#xff0c;具有高分辨率、多功能、快速扫描等优点&#xff0c;在军事和民用领域都有着广泛的应用。相控阵雷达的天线系统是其核心组成部分…

C#线性变换——缩放

前言&#xff1a; 大家好&#xff0c;我是上位机马工&#xff0c;硕士毕业4年年入40万&#xff0c;目前在一家自动化公司担任软件经理&#xff0c;从事C#上位机软件开发8年以上&#xff01;我们在C#开发中经常需要对平面中的坐标进行一些变换&#xff0c;比如缩放、旋转等&…

数据结构:二叉树、堆

目录 一.树的概念 二、二叉树 1.二叉树的概念 2.特殊类型的二叉树 3.二叉树的性质 4.二叉树存储的结构 三、堆 1.堆的概念 2.堆的实现 Heap.h Heap.c 一.树的概念 注意&#xff0c;树的同一层中不能有关联&#xff0c;否侧就不是树了&#xff0c;就变成图了&#xff…

PCL 点云配准 Trimed-ICP算法(精配准

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 perform_standard_icp 函数 2.1.2 perform_trimmed_icp 函数 2.1.3 visualize_registration 函数 2.2完整代码 PCL点云算法汇总及实战案例汇总的目录地址链接&#xff1a; PCL点云算…

国庆旅游高峰期,如何利用可视化报表来展现景区、游客及消费数据

国庆黄金周&#xff0c;作为国内旅游市场的年度盛宴&#xff0c;总是吸引着无数游客的目光。今年&#xff0c;随着旅游市场的强劲复苏&#xff0c;各大景区又再次迎来游客流量的高峰。全国国内出游7.65亿人次&#xff0c;同比增长5.9%&#xff0c;国内游客出游总花费7008.17亿元…

大型企业软件开发是什么样子的? - Web Dev Cody

引用自大型企业软件开发是什么样子的&#xff1f; - Web Dev Cody_哔哩哔哩_bilibili 一般来说 学技术的时候 我们会关注 开发语言特性 &#xff0c;各种高级语法糖&#xff0c;底层技术 但是很少有关注到企业里面的开发流程&#xff0c;本着以终为始&#xff08;以就业为导向…

界面控件Telerik UI for WPF 2024 Q3亮点 - 支持禁用数据过滤等

Telerik UI for WPF拥有超过100个控件来创建美观、高性能的桌面应用程序&#xff0c;同时还能快速构建企业级办公WPF应用程序。UI for WPF支持MVVM、触摸等&#xff0c;创建的应用程序可靠且结构良好&#xff0c;非常容易维护&#xff0c;其直观的API将无缝地集成Visual Studio…

[Linux网络编程]03-TCP协议

一.TCP协议数据通信的过程 TCP数据报如下&#xff0c;数据报中的标志位双端通信的关键。 三次握手: 1.客户端向服务端发送SYN标志位&#xff0c;请求建立连接&#xff0c;同时发送空包 2.服务端向客户端回发ACK标志位(即确认标志位&#xff0c;任何一端发送数据后都需要另一端…

asyn驱动示例-int32driver

驱动程序源代码int32Driver.c&#xff1a; #include <stddef.h> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <ctype.h>#include <cantProceed.h> #include <epicsStdio.h> #i…

官龙村捐赠图书整理有感

今天&#xff08;2024年10月20日&#xff09;&#xff0c;我有幸参加了在深圳南山区西丽官龙村举行的义工活动&#xff0c;主要任务是整理捐赠的图书&#xff0c;并根据小学和中学的需求进行分类打包。这次活动不仅让我体会到了劳动的辛苦&#xff0c;更让我感受到了助人为乐的…

【AIGC】第一性原理下的ChatGPT提示词Prompt设计:系统信息与用户信息的深度融合

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;第一性原理与ChatGPT提示词Prompt设计应用第一性原理于ChatGPT提示词Prompt设计系统信息和用户信息的融合实际应用结论 &#x1f4af;系统信息与用户信息的定义和重要性系…

鸿蒙中富文本编辑与展示

富文本在鸿蒙系统如何展示和编辑的&#xff1f;在文章开头我们提出这个疑问&#xff0c;带着疑问来阅读这篇文章。 富文本用途可以展示图文混排的内容&#xff0c;在日常App 中非常常见&#xff0c;比如微博的发布与展示&#xff0c;朋友圈的发布与展示&#xff0c;都在使用富文…

C++高阶:红黑树实现

目录 一.红黑树的概念 1.1红黑树的规则 1.2红黑树的效率 二.红黑树的实现 2.1红黑树的结构 2.2红黑树的插入 2.2.1插入的大致过程 2.2.2情况一&#xff1a;变色 ​编辑 2.2.3情况二&#xff1a;单旋变色 2.2.4情况三&#xff1a;双旋变色 2.3插入代码实现 2.4红黑树的…

【网络安全】简单P1:通过开发者工具解锁专业版和企业版功能

未经许可,不得转载。 文章目录 前言发现过程前言 在探索一个SaaS平台的过程中,我发现了一个漏洞,使得我能够在无需订阅的情况下解锁高级(专业/企业)功能。 发现过程 我使用一个没有任何高级功能的基本用户账户进行常规登录。在浏览平台时,我注意到某些按钮和功能上带有…

【C++STL】list的基本介绍与使用方式

✨ Blog’s 主页: 白乐天_ξ( ✿&#xff1e;◡❛) &#x1f308; 个人Motto&#xff1a;他强任他强&#xff0c;清风拂山冈&#xff01; &#x1f525; 所属专栏&#xff1a;C深入学习笔记 &#x1f4ab; 欢迎来到我的学习笔记&#xff01; 一、list的介绍 文档内容以及大致翻…

ROS笔记之kill掉所有ros节点rosnode

ROS笔记之kill掉所有ros节点rosnode 文章目录 ROS笔记之kill掉所有ros节点rosnode1. 杀死所有 ROS 节点&#xff08;不包括 rosmaster&#xff09;2. 杀死 rosmaster3. 验证所有节点和 rosmaster 是否已终止4. roscore 和 rosmaster 是同一个概念吗&#xff1f;5. 为什么执行 k…

【踩坑日记36】ModuleNotFoundError: No module named ‘taming‘

问题描述 ModuleNotFoundError: No module named ‘taming‘问题分析 未正确安装taming-transformers包 问题解决 从github网站中安装taming-transformers包&#xff1a; 从github网站中下载taming-transformers代码 git clone https://github.com/CompVis/taming-transfo…

微机原理与接口技术知识点总结——绪论

1.1、计算机发展概述 早期计算机的用途主要是用于算数&#xff0c;一直到20世纪电子领域基础研究的突破&#xff0c;也就是电子计算机的诞生&#xff0c;计算机才变得如此广泛。以微电子技术为基础制造的电子计算机已经完全取代了机械计算机和机电计算机&#xff0c;因此电子计…

第二十二届GOPS全球运维大会2024一日感

第二十二届GOPS全球运维大会将于2024年4月25-26日在南山区深圳湾万丽酒店召开。大会将为期2天&#xff0c;侧重大模型、AIOps、DevOps、可观测、SRE、云原生等热门技术领域。 GOPS是我一直关注的一场技术峰会&#xff0c;主要是它的侧重点在运维方面&#xff0c;这和我本身的职…