Java多线程 线程池Executor框架

简介: Java多线程 线程池Executor框架

一、说明


线程池的引出


  • 通过new语句创建一个Java对象时,JVM就会为这个对象分配一块内存空间


  • 而线程的创建和销毁需要调用操作系统内核的API,成本较高


  • 线程池是一个容纳多个线程的容器,通过复用线程来达到执行多个任务的目的,对线程进行统一的分配,调优和监控,无需重复创建线程,优化了资源开销,由此引出Executor框架


二、理解


Executor


  • java.util.cocurrent 包下Executor接口,内部使用线程池机制,控制线程的启动、执行和关闭,相比Thread.start()方法效率更高,易于管理


包括三大部分


  • 任务:被执行任务需要实现CallableRunnable接口


  • 任务的执行:把任务分派给多个线程的执行机制, ExecutorExecutorService接口及其实现类


  • 异步计算的结果: Future 接口 FutureTask实现类



  • Executor即线程池接口,其execute()方法接收Runnable接口的对象,但没有返回结果


  • ExecutorService 接口用来实现和管理多线程,提供生命周期管理方法,返回 Future 对象,当所有已经提交的任务执行完毕后将会关闭该接口


  • AbstractExecutorService 类用来提供线程接口的一些默认实现


  • ThreadPoolExecutor 线程池的实现类,通过调用Executors创建线程池并返回一个ExecutorService对象


  • ScheduledExecutorService 接口用来执行定时任务


  • ScheduledThreadPoolExecutor 用来调度定时任务的线程池实现类


Executor框架使用流程



ExecutorService


  • 继承 Executor 接口


  • submit()方法接收RunnableCallable接口的对象,有返回执行结果的对象


  • 关闭线程池调用 shutDown() 方法停止接收新任务,原来的任务继续执行;或者shutdownNow()方法停止接收新任务,原来的任务停止执行


Executors


  • 线程池工厂类,提供生成Executor(线程池)的方法,返回的线程池都实现了ExecutorService接口


  • newSingleThreadExecutor() 创建单个线程的线程池


  • newFixedThreadPool(int numOfThreads) 创建固定线程数的线程池,可控制线程最大并发数,超出的线程会在队列中等待


  • newCachedThreadPool() 根据需要创建新的线程,自动回收空闲线程,所有线程都会在限制60秒后被回收,如果回收后又创建了任务,将新创建一个线程


  • newScheduledThreadPool(int) 创建一个支持定时及周期性执行任务的线程池


三、实现


1. newSingleThreadExecutor


创建一个SingThreadExecutorTest类,单个线程的线程池执行MyThread1MyThread2任务


public class SingThreadExecutorTest {
    public static void main(String[] args) {
        // 1.创建一个单线程化的线程池
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        // 2.创建10次线程任务
        for (int i = 0; i < 5; i++) {
            // 3.执行线程任务
            executorService.execute(new MyThread1());
            executorService.execute(new MyThread2());
        }
        // 4.关闭线程池
        executorService.shutdown();
    }
    static class MyThread1 extends Thread {
        @Override
        public void run() {
            try {
                System.out.println(Thread.currentThread().getName() + "        我是任务1");
                sleep(2000);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    static class MyThread2 extends Thread {
        @Override
        public void run() {
            try {
                System.out.println(Thread.currentThread().getName() + " 我是任务2");
                sleep(2000);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}


只有单个线程池去执行10个任务



2. newFixedThreadPool


创建固定线程数的线程池,可控制线程最大并发数,超出的线程会在队列中等待


    public static void main(String[] args) {
        // 1.创建容量为5线程数的线程池
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        // 2.创建10次线程任务
        for (int i = 0; i < 5; i++) {
            // 3.执行线程任务
            executorService.execute(new MyThread1());
            executorService.execute(new MyThread2());
        }
        // 4.关闭线程池
        executorService.shutdown();
    }


5个线程去执行10个任务



3. newCachedThreadPool


根据需要创建新的线程,自动回收空闲线程,所有线程都会在限制60秒后被回收,如果回收后又创建了任务,将新创建一个线程


    public static void main(String[] args) {
        // 1.创建可缓存的线程池
        ExecutorService executorService = Executors.newCachedThreadPool();
        // 2.创建10次线程任务
        for (int i = 0; i < 5; i++) {
            // 3.执行线程任务
            executorService.execute(new MyThread1());
            executorService.execute(new MyThread2());
        }
        // 4.关闭线程池
        executorService.shutdown();
    }


根据需要自动创建新线程去只执行10个任务



当线程运行时间超过60秒时


    public static void main(String[] args) throws InterruptedException {
        // 1.创建可缓存的线程池
        ExecutorService executorService = Executors.newCachedThreadPool();
        // 2.创建线程任务执行
        for (int i = 0; i < 5; i++) {
            executorService.execute(new MyThread1());
        }
        Thread.sleep(30000);
        System.out.println("睡眠30秒");
        for (int i = 0; i < 5; i++) {
            executorService.execute(new MyThread1());
        }
        Thread.sleep(65000);
        System.out.println("睡眠65秒");
        for (int i = 0; i < 5; i++) {
            executorService.execute(new MyThread1());
        }
        // 4.关闭线程池
        executorService.shutdown();
    }


5个线程执行任务再休眠30秒后,线程并未被回收,继续用这5个线程执行任务,休眠65秒后,线程被回收,新建5个线程执行任务



4. newScheduledThreadPool


创建一个支持定时及周期性执行任务的线程池


public class SingThreadExecutorTest {
    public static void main(String[] args) {
        // 1.创建容量为5线程数的线程池
        ScheduledExecutorService executorService = Executors.newScheduledThreadPool(5);
        // 2.创建10次线程任务
        for (int i = 0; i < 5; i++) {
            // 3.执行线程任务
            executorService.schedule(new MyThread1(),5000 , TimeUnit.MILLISECONDS);
            executorService.schedule(new MyThread2(),1000 , TimeUnit.MILLISECONDS);
        }


5个线程去执行10个任务,任务2马上就执行完成了,而任务1要延迟5秒才执行完成


目录
相关文章
|
1月前
|
人工智能 Java 开发者
阿里出手!Java 开发者狂喜!开源 AI Agent 框架 JManus 来了,初次见面就心动~
JManus是阿里开源的Java版OpenManus,基于Spring AI Alibaba框架,助力Java开发者便捷应用AI技术。支持多Agent框架、网页配置、MCP协议及PLAN-ACT模式,可集成多模型,适配阿里云百炼平台与本地ollama。提供Docker与源码部署方式,具备无限上下文处理能力,适用于复杂AI场景。当前仍在完善模型配置等功能,欢迎参与开源共建。
938 58
阿里出手!Java 开发者狂喜!开源 AI Agent 框架 JManus 来了,初次见面就心动~
|
15天前
|
消息中间件 缓存 Java
Spring框架优化:提高Java应用的性能与适应性
以上方法均旨在综合考虑Java Spring 应该程序设计原则, 数据库交互, 编码实践和系统架构布局等多角度因素, 旨在达到高效稳定运转目标同时也易于未来扩展.
74 8
|
15天前
|
存储 算法 安全
Java集合框架:理解类型多样性与限制
总之,在 Java 题材中正确地应对多样化与约束条件要求开发人员深入理解面向对象原则、范式编程思想以及JVM工作机理等核心知识点。通过精心设计与周密规划能够有效地利用 Java 高级特征打造出既健壮又灵活易维护系统软件产品。
47 7
|
14天前
|
设计模式 缓存 安全
【JUC】(6)带你了解共享模型之 享元和不可变 模型并初步带你了解并发工具 线程池Pool,文章内还有饥饿问题、设计模式之工作线程的解决于实现
JUC专栏第六篇,本文带你了解两个共享模型:享元和不可变 模型,并初步带你了解并发工具 线程池Pool,文章中还有解决饥饿问题、设计模式之工作线程的实现
69 2
|
2月前
|
存储 缓存 安全
Java集合框架(二):Set接口与哈希表原理
本文深入解析Java中Set集合的工作原理及其实现机制,涵盖HashSet、LinkedHashSet和TreeSet三大实现类。从Set接口的特性出发,对比List理解去重机制,并详解哈希表原理、hashCode与equals方法的作用。进一步剖析HashSet的底层HashMap实现、LinkedHashSet的双向链表维护顺序特性,以及TreeSet基于红黑树的排序功能。文章还包含性能对比、自定义对象去重、集合运算实战和线程安全方案,帮助读者全面掌握Set的应用与选择策略。
186 23
|
1月前
|
SQL Java 数据库连接
区分iBatis与MyBatis:两个Java数据库框架的比较
总结起来:虽然从技术角度看,iBATIS已经停止更新但仍然可用;然而考虑到长期项目健康度及未来可能需求变化情况下MYBATISS无疑会是一个更佳选择因其具备良好生命周期管理机制同时也因为社区力量背书确保问题修复新特征添加速度快捷有效.
114 12
|
2月前
|
存储 缓存 安全
Java集合框架(三):Map体系与ConcurrentHashMap
本文深入解析Java中Map接口体系及其实现类,包括HashMap、ConcurrentHashMap等的工作原理与线程安全机制。内容涵盖哈希冲突解决、扩容策略、并发优化,以及不同Map实现的适用场景,助你掌握高并发编程核心技巧。
|
存储 监控 Java
Java多线程优化:提高线程池性能的技巧与实践
Java多线程优化:提高线程池性能的技巧与实践
458 1
|
设计模式 监控 Java
Java多线程基础-11:工厂模式及代码案例之线程池(一)
本文介绍了Java并发框架中的线程池工具,特别是`java.util.concurrent`包中的`Executors`和`ThreadPoolExecutor`类。线程池通过预先创建并管理一组线程,可以提高多线程任务的效率和响应速度,减少线程创建和销毁的开销。
777 2
|
Java 数据库
【Java多线程】对线程池的理解并模拟实现线程池
【Java多线程】对线程池的理解并模拟实现线程池
147 1