线程池高手进阶:揭秘ThreadPoolExecutor的小妙招!

这篇具有很好参考价值的文章主要介绍了线程池高手进阶:揭秘ThreadPoolExecutor的小妙招!。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

线程池高手进阶:揭秘ThreadPoolExecutor的小妙招!,java,开发语言

RejectedExecutionHandler总结

ThreadPoolExecutor 是 Java 中用于创建和管理线程池的接口,当线程池中的任务队列已满,并且线程池中的线程数量已经达到最大时,如果再有新的任务提交,就需要一个策略来处理这些无法执行的任务。它 提供了四种拒绝策略,都是 RejectedExecutionHandler 接口的实现,如下:

  1. AbortPolicy(默认策略):直接抛出一个 RejectedExecutionException 异常。
  2. CallerRunsPolicy:调用执行任务的 execute 方法的线程来运行任务,如果执行程序已经关闭,那么任务将被抛弃。
  3. DiscardPolicy:无法执行的任务将被抛弃,不会抛出任何异常。
  4. DiscardOldestPolicy:如果执行程序尚未关闭,则位于工作队列头部的任务将被删除,然后重试执行任务(如果再次失败,则重复此过程)。

以下是使用ThreadPoolExecutor的代码示例,如下:

import java.util.concurrent.*;  
  
public class ThreadPoolExecutorDemo {  
    public static void main(String[] args) {  
        // 创建一个固定大小的线程池  
        int corePoolSize = 2;  
        int maximumPoolSize = 4;  
        long keepAliveTime = 10L;  
        TimeUnit unit = TimeUnit.SECONDS;  
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(2);  
  
        // 使用不同的拒绝策略  
        RejectedExecutionHandler abortPolicy = new ThreadPoolExecutor.AbortPolicy();  
        RejectedExecutionHandler callerRunsPolicy = new ThreadPoolExecutor.CallerRunsPolicy();  
        RejectedExecutionHandler discardPolicy = new ThreadPoolExecutor.DiscardPolicy();  
        RejectedExecutionHandler discardOldestPolicy = new ThreadPoolExecutor.DiscardOldestPolicy();  
  
        // 创建线程池并设置拒绝策略  
        ThreadPoolExecutor executor1 = new ThreadPoolExecutor(  
                corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, abortPolicy);  
  
        ThreadPoolExecutor executor2 = new ThreadPoolExecutor(  
                corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, callerRunsPolicy);  
  
        ThreadPoolExecutor executor3 = new ThreadPoolExecutor(  
                corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, discardPolicy);  
  
        ThreadPoolExecutor executor4 = new ThreadPoolExecutor(  
                corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, discardOldestPolicy);  
  
        // 提交任务  
        for (int i = 0; i < 10; i++) {  
            final int taskId = i;  
            executor1.execute(() -> System.out.println("Executing task " + taskId + " with AbortPolicy"));  
            executor2.execute(() -> System.out.println("Executing task " + taskId + " with CallerRunsPolicy"));  
            executor3.execute(() -> System.out.println("Executing task " + taskId + " with DiscardPolicy"));  
            executor4.execute(() -> System.out.println("Executing task " + taskId + " with DiscardOldestPolicy"));  
        }  
  
    }  
}

在上面的代码示例中,由于工作队列和线程池的大小都设置得很小,所以提交的任务会很快填满队列和线程池,从而触发拒绝策略,不同的拒绝策略适用于不同的场景,在实际应用中,应该根据具体需求来合理设置线程池的大小、工作队列的容量以及拒绝策略。

ThreadFactory总结

ThreadFactory接口常用于在ThreadPoolExecutor中管理控制线程的名称、优先级、是否守护线程以及其他线程属性。下面是一个简单的ThreadFactory使用案例,案例中定义了一个CustomThreadFactory类,如下代码:

import java.util.concurrent.ThreadFactory;  
import java.util.concurrent.atomic.AtomicInteger;  
  
public class CustomThreadFactory implements ThreadFactory {  
    private final String prefix;  
    private final AtomicInteger threadNumber = new AtomicInteger(1);  
  
    public CustomThreadFactory(String prefix) {  
        this.prefix = prefix;  
    }  
  
    @Override  
    public Thread newThread(Runnable r) {  
        // 创建一个新线程  
        Thread thread = new Thread(r);  
        // 设置线程名称,使用前缀和递增的数字  
        thread.setName(prefix + "-" + threadNumber.getAndIncrement());  
        // 可以设置其他属性,比如优先级、守护状态等  
        // thread.setPriority(Thread.MAX_PRIORITY);  
        // thread.setDaemon(false);  
        return thread;  
    }  
}

在上面代码中:

  1. CustomThreadFactory类实现了ThreadFactory接口,并重写了newThread方法。
  2. 构造函数接受一个prefix参数,用于生成线程名称的前缀。
  3. 使用AtomicInteger来生成唯一的线程编号,确保在多线程环境下编号不会重复。
  4. newThread方法中,创建一个新的Thread对象,并通过setName方法设置线程的名称,这里使用前缀和递增的编号来构建线程名称,方便在日志或调试时识别线程。
  5. 还可以根据需要调用其他Thread方法来设置线程的优先级、守护状态等属性。

如下是CustomThreadFactory的使用方法,如下:

import java.util.concurrent.ThreadPoolExecutor;  
import java.util.concurrent.TimeUnit;  
import java.util.concurrent.SynchronousQueue;  
  
public class ThreadPoolExample {  
    public static void main(String[] args) {  
        // 创建一个具有自定义线程工厂的线程池  
        ThreadPoolExecutor executor = new ThreadPoolExecutor(  
            5, // corePoolSize  
            10, // maximumPoolSize  
            60L, // keepAliveTime  
            TimeUnit.SECONDS, // unit for keepAliveTime  
            new SynchronousQueue<>(), // workQueue  
            new CustomThreadFactory("CustomThreadPool-") // 自定义线程工厂  
        );  
  
        // 提交任务给线程池  
        for (int i = 0; i < 20; i++) {  
            final int taskId = i;  
            executor.submit(() -> {  
                // 执行任务  
                System.out.println("Task " + taskId + " is running on thread " + Thread.currentThread().getName());  
            });  
        }  
  
        // 关闭线程池(这通常是在应用程序关闭时完成的)  
        // executor.shutdown();  
    }  
}

线程池高手进阶:揭秘ThreadPoolExecutor的小妙招!,java,开发语言

END!文章来源地址https://www.toymoban.com/news/detail-822532.html

到了这里,关于线程池高手进阶:揭秘ThreadPoolExecutor的小妙招!的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Vue前端】vue使用笔记0基础到高手第2篇:Vue进阶知识点介绍(附代码,已分享)

    本系列文章md笔记(已分享)主要讨论vue相关知识。Vue.js是前端三大新框架:Angular.js、React.js、Vue.js之一,Vue.js目前的使用和关注程度在三大框架中稍微胜出,并且它的热度还在递增。Vue.js是一个轻巧、高性能、可组件化的MVVM库,同时拥有非常容易上手的API。Vue.js是一个构建

    2024年02月19日
    浏览(44)
  • 自定义线程池 ThreadPoolExecutor

    Executor框架最核心的类是ThreadPoolExecutor,它是线程池的实现类,主要由下列4个组件构成。 ·corePool:核心线程池的大小。 ·maximumPool:最大线程池的大小。 ·BlockingQueue:用来暂时保存任务的工作队列。 ·RejectedExecutionHandler:当ThreadPoolExecutor已经关闭或ThreadPoolExecutor已经饱和时

    2024年02月05日
    浏览(34)
  • 进程与线程、线程创建、线程周期、多线程安全和线程池(ThreadPoolExecutor)

    什么进程? 进程是 资源(CPU、内存等)分配 的基本单位,它是程序执行时的一个实例。程序运行时系统就会创建一个进程,并为它分配资源,然后把该进程放入进程就绪队列,进程调度器选中它的时候就会为它分配CPU时间,程序开始真正运行。 什么是线程? 线程是操作系

    2024年02月14日
    浏览(40)
  • Java - ThreadPoolExecutor线程池分析

    首先ThreadPoolExecutor中,一共提供了7个参数,每个参数都是非常核心的属性,在线程池去执行任务时,每个参数都有决定性的作用。 但是如果直接采用JDK提供的方式去构建,可见设置的核心参数最多就两个,这样就会导致对线程池的控制粒度很粗。所以在阿里规范中也推荐自

    2024年02月10日
    浏览(48)
  • java线程池ThreadPoolExecutor使用

    在开发服务端软件项目时,软件经常需要处理执行时间很短而数目巨大的请求,如果为每一个请求创建一个新的线程,则会导致性能上的瓶颈。因为JVM需要频繁的处理线程对象的创建与销毁,如果请求的执行时间很短,则有可能花在创建和销毁线程对象上的时间大于真正执行

    2024年02月06日
    浏览(53)
  • ThreadPoolExecutor线程池内部处理浅析

    我们知道如果程序中并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束时,会因为频繁创建线程而大大降低系统的效率,因此出现了线程池的使用方式,它可以提前创建好线程来执行任务。本文主要通过java的ThreadPoolExecutor来查看线程池的内部处理过程。

    2024年02月05日
    浏览(45)
  • 线程池ThreadPoolExecutor底层原理源码分析

    ThreadPoolExecutor中提供了两种执行任务的方法: void execute(Runnable command) Future? submit(Runnable task) 实际上submit中最终还是调用的execute()方法,只不过会返回⼀个Future对象,用来获取任务执行结果: execute(Runnable command)方法执行时会分为三步: 注意:提交⼀个Runnable时,不管当前线程

    2024年02月06日
    浏览(64)
  • Java多线程 - 创建线程池的方法 - ThreadPoolExecutor和Executors

    线程池介绍 什么是线程池 ? 线程池就是一个可以复用线程的技术。 不使用线程池的问题 : 如果用户每发起一个请求,后台就创建一个新线程来处理,下次新任务来了又要创建新线程,而创建新线程的开销是很大的,这样会严重影响系统的性能。 线程池工作原理 : 例如线程池

    2023年04月16日
    浏览(48)
  • 全网最详细的线程池 ThreadPoolExecutor 详解,建议收藏!

    五种状态: 线程池的 shutdown() 方法,将线程池由 RUNNING(运行状态)转换为 SHUTDOWN状态 线程池的 shutdownNow() 方法,将线程池由RUNNING 或 SHUTDOWN 状态转换为 STOP 状态。 注: SHUTDOWN 状态 和 STOP 状态 先会转变为 TIDYING 状态,最终都会变为 TERMINATED ThreadPoolExecutor 继承自 AbstractExe

    2024年02月03日
    浏览(46)
  • Spring高手之路3——揭秘Spring依赖注入和SpEL表达式

    本篇会给大家举出各种 Spring 属性依赖注入的例子,方便大家理解。 我们在前面的文章中已经使用过 XML 进行 setter 方法的属性注入了,下面让我们再来回顾一下: 我们在前面的文章中也学习过如何在 bean 创建时通过编程方式设置属性: 使用XML进行setter方法注入 首先,我们需

    2024年02月08日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包