多线程之线程池的应用

多线程与线程池在操作系统中的应用 在实际应用中,需要注意合理管理线程的数量和资源,避免线程过多导致系统负载过重或资源竞争的问题。另外,需要注意线程之间的同步与互斥,以避免并发访问共享资源时出现的数据竞争和不一致性的问题。通过合理地使用它们,可以提高程序的性能和资源利用率,适用于并发处理请求、图形界面应用和大数据处理等场景。在实际开发中,需要根据具体需求选择合适的并发模型,并注意线程管理和同步机制,以确保程序的正确性和稳定性。例如,一个线程负责用户界面的渲染,另一个线程负责处理用户的输入事件。类创建了一个新的线程,并指定了线程执行的函数为。 阅读详情

我们在开发的过程中经常会遇到多线程问题,多线程在整个java基础也是计较重要的知识点。今天跟大家分享一个我在写程序过程中遇到的线程池的简单应用。

在Java1.5中提供了一个非常高效实用的多线程包:java.util.concurrent,提供了大量高级工具,可以帮助开发者编写高效易维护、结构清晰的Java多线程程序。

线程池?

之前我们在使用多线程都是用Thread的start()来创建启动一个线程,但是在实际开发中,如果每个请求到达就创建一个新线程,开销是相当大的。服务器在创建和销毁线程上花费的时间和消耗的系统资源都相当大,甚至可能要比在处理实际的用请求的时间和资源要多的多。除了创建和销毁线程的开销之外,活动的线程也需要消耗系统资源。如果在一个jvm里创建太多的线程,可能会使系统由于过度消耗内存或“切换过度”而导致系统资源不足。这就引入了线程池概念。

线程池的原理其实就是对多线程的一个管理(可以抽象的理解为原来是一个工厂来订单了,老板就聘请一个工人(线程)干活,干完活就把他炒鱿鱼了,这样每次来订单都得聘请一个工人,且老板得不停去聘请工人,并分配任务,现在老板就请了一个主管(线程池),并和工人签订长期合同,这样每次有订单(任务)来了,直接交给主管调度工人去干活),为了实现异步机制的一种方法,其实就是多个线程执行多个任务,最终这些线程通过线程池进行管理…不用手动去维护…一次可以处理多个任务,这样就可以迅速的进行响应…

在java.util.concurrent包下,提供了一系列与线程池相关的类。合理的使用线程池,可以带来多个好处:

  • (1)降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗;
  • (2)提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行;
  • (3)提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。
  • (4)线程池可以应对突然大爆发量的访问,通过有限个固定线程为大量的操作服务,减少创建和销毁线程所需的时间。

如何使用?

1.创建线程池

2.创建任务

3.执行任务

4.关闭线程池

一、创建线程池的方法

我们一般通过工具类Executors的静态方法来获取线程池或静态方法。

介绍四种常用创建方法

1. ExecutorService executorService1 = Executors.newSingleThreadExecutor();

单例线程,表示在任意的时间段内,线程池中只有一个线程在工作…

2. ExecutorService executorService2 = Executors.newFixedThreadPool(10);

固定线程池,表示创建一个可复用的固定线程池,线程池中最大线程个数为10,当有任务被提交时,创建一个线程去执行,直到达到当线程池中最大个数为止。当提交的任务个数大于线程池中最大线程个数时,则存入队列中,等待执行。如果某个线程在执行期间发生了异常而终止,会补充一个新线程去执行余下。

3. ExecutorService executorService3 = Executors.newScheduledThreadPool();

调度型线程池,一个大小无限的线程池,线程池会根据Scheduled(任务列表)进行延迟执行,或者是进行周期性的执行.适用于一些周期性的工作.支持定时以及周期性执行任务的需求任务。

4. ExecutorService executorService4 = Executors.newCacheThreadPool();

缓存线程池,无固定大小缓存线程池,先查看线程池中是否有当前执行线程的缓存,如果有就resue(复用),如果没有,那么需要创建一个线程来完成当前的调用.并且这类线程池只能完成一些生存期很短的一些任务.并且这类线程池内部规定能resue(复用)的线程,空闲的时间不能超过60s,一旦超过了60s,就会被移出线程池.非常灵活
例子

public class Executor {
    public static void main(String[] args) {
        //定义了线程池中最大存在的线程数目
        ExecutorService executorService=Executors.newFixedThreadPool(10);
        //添加了一个任务...
        executorService.execute(new Runnable() {

            @Override
            public void run() {
                while(true){
                    System.out.println("begincode");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }
}

执行结果就是无限循环每隔1秒打印一个begincode…

二、创建任务

任务分为两种一种是有返回值的,一种是没有返回值的

  • 无返回值的任务就是一个实现了runnable接口的类.使用run方法
  • 有返回值的任务是一个实现了callable接口的类.使用call方法
public class Begincode implements Runnable {
    public void run() {
        System.out.println(“Begincode--runable”);
    }  
} 

public class Begincode implements callable{
    public String call() {
        System.out.println(“Begincode--callable”);
        return "Begincode";
    }
} 

三、执行任务

通过java.util.concurrent.ExecutorService接口对象来执行任务,该对象有两个方法可以执行任务execute和submit

  • execute这种方式提交没有返回值,也就不能判断是否执行成功。

  • submit这种方式它会返回一个Future对象,通过future的get方法来获取返回值,get方法会阻塞住直到任务完成。

四、关闭线程池

当我们不需要使用线程池的时候,我们需要对其进行关闭…有两种方法可以关闭掉线程池…

  • shutdown()

    • shutdown并不是直接关闭线程池,而是不再接受新的任务…如果线程池内有任务,那么把这些任务执行完毕后,关闭线程池….
  • shutdownNow()

    • shutdownNow这个方法表示不再接受新的任务,并把任务队列中的任务直接移出掉,如果有正在执行的,尝试进行停止…

五、案例分享

场景:从数据库中获取url,并利用httpclient循环访问url地址,并对返回结果进行操作
分析:由于是循环的对多个url进行访问并获取数据,为了执行的效率,考虑使用多线程,url数量未知如果每个任务都创建一个线程将消耗大量的系统资源,最后决定使用线程池。

public class GetMonitorDataService {

    private Logger logger = LoggerFactory.getLogger(GetMonitorDataService.class);
    @Resource
    private MonitorProjectUrlMapper groupUrlMapper;
    @Resource
    private MonitorDetailBatchInsertMapper monitorDetailBatchInsertMapper;
    public void sendData(){
        //调用dao查询所有url
        MonitorProjectUrlExample example=new MonitorProjectUrlExample();
        List<MonitorProjectUrl> list=groupUrlMapper.selectByExample(example);
        logger.info("此次查询数据库中监控url个数为"+list.size());

        //获取系统处理器个数,作为线程池数量
        int nThreads=Runtime.getRuntime().availableProcessors();

        //定义一个装载多线程返回值的集合
        List<MonitorDetail> result= Collections.synchronizedList(new ArrayList<MonitorDetail>());
        //创建线程池,这里定义了一个创建线程池的工具类,避免了创建多个线程池
        ExecutorService executorService = ThreadPoolFactoryUtil.getExecutorService(nThreads);
        //遍历数据库取出的url
        if(list!=null&&list.size()>0) {
            for (MonitorProjectUrl monitorProjectUrl : list) {
                String url = monitorProjectUrl.getMonitorUrl();
                //创建任务
                ThreadTask threadTask = new ThreadTask(url, result);
                //执行任务
                executorService.execute(threadTask);
            }
            //对数据进行操作
            saveData(result);
        }
    }

任务:

public class ThreadTask implements Runnable{
    //这里实现runnable接口
    private String url;
    private List<MonitorDetail> list;
    public ThreadTask(String url,List<MonitorDetail> list){
        this.url=url;
        this.list=list;
    }
    //把获取的数据进行处理
    @Override
    public void run() {
        MonitorDetail detail = HttpClientUtil.send(url, MonitorDetail.class);
        list.add(detail);
    }

}

文中案例为监控系统故没有关闭线程池


以上是本人的一些分享,希望和大家多多交流。如果哪里有不足,希望指出!

C# Winform中的异步多线程和线程池技术深入应用 htmltable {th, td {th {pre {简介:在Windows桌面应用开发中,C#的线程和线程池技术对提升程序响应性和效率至关重要。本文深入探讨Winform应用中的异步多线程和线程池技术的使用,包括线程的基础使用、异步编程实践、线程池的高效任务管理,以及线程安全的日志记录。此外,还展示了如何在实际项目中整合这些技术以实现高效的数据库操作和日志记录,从而创建出性能优良的桌面应用程序。 阅读详情

相关推荐

Java数据库查询的多线程与线程池应用技巧

线程池有多个核心参数,它们共同决定了线程池的行为和性能。主要包括::核心线程数,线程池中始终存活的线程数量。:最大线程数,线程池中能创建的最大线程数量。:非核心线程的空闲存活时间,超过该时间空闲线程会被回收。unit:空闲存活时间的单位,如。workQueue:任务队列,存放待执行任务。:线程工厂,用于创建新线程。handler:拒绝策略,当任务过多时如何处理。

weixin_33375360的博客 593

多线程以及线程池详解

多线程以及线程池详解

weixin_42456784的博客 737

通用多线程模块(jdk线程池的运用)

介绍一个通用多线程服务模块。是利用jdk线程池,多线程并行处理多任务,以提高执行效率。

多线程-线程池的运用

我们日常工作中常见的有数据库连接池、线程池、对象池等,它们的特点都是将 “昂贵的”、“费时的” 的资源维护在一个特定的 “池子” 中,规定其最小连接数、最大连接数、阻塞队列等配置,方便进行统一管理和复用,通常还会附带一些探活机制、强制回收、监控一类的配套功能。先启动若干数量的线程,并让这些线程都处于睡眠状态,当需要一个开辟一个线程去做具体的工作时,就会唤醒线程池中的某一个睡眠线程,让它去做具体工作,当工作完成后,线程又处于睡眠状态,而不是将线程销毁。所以我们最好自己手动创建线程池。

qq_54414566的博客 330

JAVA多线程运用

1. 建立三个线程,并且同时运行它们。当运行时输出线程的名称。 实验步骤: (1)、创建类sy6_1 (2)、创建三个线程,调用start()方法启动这三个线程 (3)、保存文件,调试并编译运行程序。 参考程序运行效果: 2. 实现3个类:Storage、Counter和Printer。 Storage类应存储整数。 Counter应创建线程,线程从0开始计数(0,1,2,3…)并将每个值存储到Storage类中。 Printer类应创建一个线程,线程读取Storage类中的值并打印值。编写程序创建Storage类的实例,并创建一个Counter对象和Printer对象操作此实例。 实验步骤: (1)、创建三个类Counter, Printer,Storage (2)、创建TestCounter类,在该类中定义main函数,在main函数中定义Storage对象、Counter对象和 Printer对象,创建Counter线程和Printer线程并启动 (3)、保存文件,调试并编译运行程序。 参考程序运行效果: 3. 修改实验1第2题的程序,添加适当代码,以确保每个数字都恰好只被打印一次。 实验步骤: (1)、创建三个类Counter, Printer,Storage (2)、 创建TestCounter类,在该类中定义main函数,在main函数中定义Storage对象、Counter1对象和 Printer对象,创建Counter线程和Printer线程并启动 (3)、在定义Storage类中的setValue(int i) 和getValue ()方法时使用synchronized关键字,将其定义为同步方法 (4)、保存文件,调试并编译运行程序。 参考程序运行效果:

LLC谐振电路增益公式推导

LLC谐振电路增益公式理解

金凯*博客 1万+

多线程--线程和线程池的用法

进程和线程,创建线程的方式,继承 Thread 的方式(无返回值),实现Runnable接口(无返回值),实现Callable接口(有返回值),线程的生命周期,线程池,为什么要使用线程池,使用线程池的优势,线程池的应用场景,参数名参数含义核心线程数最大线程数空闲线程存活时间unit时间单位workQueue线程池任务队列创建线程的工厂handler拒绝策略。线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。线程池不仅能够保证内核的充分利用,还能防止过分调度。进程开始时创建一定数量的线程加到池中..

m0_57640408的博客 2077

建议收藏:华为海思IC设计笔试题,含解析(附下载)

接触过的部门有麒麟芯片、CPU/GPU,总体面试感觉非常好,规范且认真,第一轮手撕代码状态机+复盘机考题+瞄准几个知识点深挖,时间1hour+;一二轮面试是连着的,所以很累。但是岗位就那么多,在面试的时候,很多同学因为准备不充分,与岗位失之交臂,无缘进入该公司。时序电路有记忆功能,不会产生锁存器,锁存器一般在组合逻辑中case写不全,else写不全,或者敏感列表写不全。

nuoweishizi的博客 3288

Java高级编程十二:多线程及线程池的使用

第十二章 多线程 1.基本概念:程序、进程、线程 程序(Program) 为了完成特定的任务、用某种语言编写的一组指令的集合,即指一段静态的代码,静态对象 进程(process) 是程序的一次执行过程,或是正在运行的程序,是一个动态的过程,有自身的生命周期 线程(thread) 进程可以进一步细分为线程,是一个程序内部的一条执行路径 若一个进程同一时间并行执行多个线程,就是支持多线程的 线程最为调度和执行的单位,每个线程都拥有独立的运行栈和程序计数器(pc),线程切换的开销小 一个进程的多个线程

qq_42059717的博客 2864

手把手教你用Matlab解析Zygo .dat文件:从二进制数据到面形图(附完整流程)

本文详细介绍了如何使用Matlab解析Zygo干涉仪生成的.dat文件,从二进制数据读取到面形图可视化的完整流程。通过实例代码演示了文件结构解析、数据矩阵读取、高阶Zernike拟合等关键技术,帮助工程师和研究人员高效处理光学检测数据,提升分析精度和工作效率。

weixin_30731305的博客 447

DFT实训教程笔记2(bibili版本)- Scan synthesis practice

文章目录Scan synthesis practice 本博文是博主记录DFT实训教程的笔记版本,此笔记并没有对所有的知识进行记录,仅仅以自身的认知水平,来记录了一些部分笔记并加上了自己的理解。 Scan synthesis practice How to design scan clock structure? 假设一块chip里面有好几十个clock domain,如果每一个clock domain都用一个scan clock虽然会非常清晰,但是IO数目肯定不够用。 clock group: 1、no

ciscomonkey的博客 9082

多线程-线程池的使用

当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态。线程对象在不同的时期有不同的状态。那么 Java 中的线程存在哪几种状态呢?Java 中的线程/* 新建 */NEW ,/* 可运行状态 */RUNNABLE ,/* 阻塞状态 */BLOCKED ,/* 无限等待状态 */WAITING ,/* 计时等待 *//* 终止 */TERMINATED;// 获取当前线程的状态。

2302_81141145的博客 1057

【RT-DETR有效改进】计算训练好权重文件对应的FPS、推理每张图片的平均时间(科研必备)

本文给大家带来的改进机制是利用我们训练好的权重文件计算FPS,同时打印每张图片所利用的平均时间,模型大小(以MB为单位),同时支持batch_size功能的选择,对于轻量化模型的读者来说,本文的内容对你一定有帮助,可以清晰帮你展示出模型速度性能的提升以及轻量化的效果(模型大小),对于以提高精度为目的的读者本文也能够帮助大家展示出现阶段的模型速度指标。所以本文的内容是十分有用的机制,对于大家发表论文来说,下面的图片为运行后的效果可以看到,该有的指标均已打印(本文内容为我独家创新,全网无第二份)下面是效果图和文

Snu77的博客 3628

多线程与线程池在Java中的应用实践

本文系统探讨了多线程编程及其在Java中的实现方式,重点分析了线程池的设计与应用。文章首先介绍了多线程的基础概念、优势及挑战,包括线程安全问题、死锁等;随后详细阐述了Java中三种多线程实现方式(Thread类、Runnable接口、Callable接口)及其适用场景。在进阶部分,深入讲解了线程同步机制(synchronized、Lock工具类)、线程通信方式以及原子类的使用。针对线程池,文章从核心概念、参数配置到高级特性(拒绝策略、线程工厂等)进行了全面解析,并提供了实际项目案例(RFID系统)的代码实现

沉浮yu大海的博客 887

从零构建爬虫抓取故宫数字文物库:Python最新实战技术详解

熟悉了动态内容加载的网页结构解析技巧。掌握了 Playwright + BeautifulSoup 的组合用法。实现了从网页→JSON→详情→图像的完整数据闭环。掌握了结构化保存与可视化分析能力。

2201_76125261的博客 1307

7.29华为OD机试真题 新系统 - 能量对撞 (Java/Py/C/C++/Js/Go)

7.29华为OD机试真题 新系统 - 能量对撞 (Java/Py/C/C++/Js/Go)

算法大师! 1321

Java并发编程基础(二)——多线程——线程池的应用

Java并发编程基础(二)——多线程——线程池的应用

qq_46274911的博客 930

汽车UDS诊断之诊断会话控制服务(0x10)深度剖析

DiagnosticSessionControl就是诊断会话控制。 请求消息定义 A_Data类型 参数名称 Cvt 字节值 助记符 #1 诊断会话控制请求SID M 0x10 DSC #2 子功能=[诊断会话类型] M 0x00-0xFF LEV_DS_ ...

心骗小白话的博客 7419

线程池在Java多线程中的应用

随着计算机硬件和软件技术的不断发展,多线程编程在软件开发中变得越来越常见。然而,使用多线程编程时必须小心谨慎,以确保正确性和可维护性。在这个过程中,线程池成为了一个至关重要的工具。本文将介绍其应用场景、注意事项以及与同步机制的关系。

一名Java语言狂热分子。 2119

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

提升Qt应用性能的利器:线程池与多线程使用指南

提升Qt应用性能的利器:线程池与多线程使用指南 去发现同类优质开源项目:https://gitcode.com/ 项目介绍 在现代软件开发中,性能优化是不可或缺的一环。特别是在处理频繁的I/O操作或耗时任务时,如何有效地利用多线程技术来提升程序的响应速度和效率,成为了开发者们关注的焦点。为了帮助Qt开发者更好地掌握这一技术,我们推出了《Qt线程池与多线程使用指南》。 本指南详细介绍了如何在Qt中创...

gitblog_09722的博客 497

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

【多线程】深入剖析线程池的应用

线程池亦是如此,它预先创建了一组可重用的线程,当有新的任务提交给线程池时,线程池就会从池中取出一个空闲的线程来执行这个任务;而当线程完成任务后,它并不会被销毁,而是再次返回到线程池中等待下一个任务。从而大幅提高线程利用率,提升效率。

acm_pn的博客 937

多线程应用——线程池

一次创建多个线程,放在一个池子(集合类),用的时候拿一个,用完了之后就放回这个池子就可以了。

WangSir 1130

多线程的应用与原理分析11(线程池)

线程池 Java中的线程池是运用场景最多的并发框架,几乎所有需要异步或并发执行任务的程序都可以使用线程池;线程池就像数据库连接池的作用类似,只是线程池是用来重复管理线程避免创建大量线程增加开销。所以合理的使用线程池可以。 1. 降低创建线程和销毁线程的性能开销; 2. 合理的设置线程池大小可以避免因为线程数超出硬件资源瓶颈带来的问题,类似起到了限流的作用;线程...

zy345293721的博客 298

【多线程案例】线程池的应用及实现

线程池就相当于一个池子,里面有很多的创建好的线程,可以进行统一的管理。当我们使用线程的时候,直接从里面调取,而不用在频繁的创建与销毁。降低了线程创建销毁的开销:不用频繁的创建销毁线程,减少了资源 的开销;提高系统的稳定性:线程池中的线程是有限的的,避免了创建了大量线程,造成系统崩溃;提高资源的利用率:线程池能够合理的分配系统资源(CPU时间,内存等),提高资源的利用率;方便管理线程:线程池中的线程可以统一进行管理,方便创建,暂停,启动,销毁等操作;

是小辰 351

多线程之线程池Executor应用

JDK1.5之后,提供了自带的线程池,以便我们更好的处理线程并发问题。 Executor类给我提供了多个线程池创建的方式:    创建固定的线程池 Executors.newFixedThreadPool(2)    创建可变的缓冲线程池 Executors.newCachedThreadPool()    创建单一的线程池 Executors.newSingleThreadExecuto

Andyの笔记 1302
上一篇: 设计模式之单例模式
下一篇: springBoot集成shiro+redis遇到的坑
bubble21
博客等级 码龄9年 33粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值