java ThreadPoolExecutor 并发调用实例详解

Java ThreadPoolExecutor 并发调用实例详解

Java中的线程池可以提高应用程序的性能和可伸缩性。ThreadPoolExecutor是一个实现了ExecutorService接口的线程池类。通过ThreadPoolExecutor的配置,可以定制线程池的大小、任务队列大小、线程空闲时间等参数,以适应不同的应用场景。

ThreadPoolExecutor的构造方法

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
  • corePoolSize:指定线程池的基本大小,即对外提供线程的数量。
  • maximumPoolSize:指定线程池中允许的最大线程数。
  • keepAliveTime:指定线程池中线程保持空闲状态的时间。
  • unit:指定keepAliveTime参数的时间单位。
  • workQueue:指定一个阻塞队列,用于存储等待执行的任务。
  • threadFactory:指定创建线程的工厂类。
  • handler:指定当待执行的任务超出线程池最大容量时的处理策略。

ThreadPoolExecutor的状态

ThreadPoolExecutor一共拥有5种状态:

  • RUNNING:线程池在正常运行状态下接收新任务,并且可以处理阻塞队列中的任务。
  • SHUTDOWN:线程池不再接收新任务,但是可以处理阻塞队列中的任务。
  • STOP:线程池不再接收新任务,并且不再处理阻塞队列中的任务,正在执行的任务也可以被中断。
  • TIDYING:当任务队列和线程池都为空时,线程池到达TIDYING状态,当完成状态转换后会调用terminated()方法。
  • TERMINATED:terminated()方法执行完毕后,线程池到达TERMINATED状态。

例子1:自定义拒绝策略

public static void main(String[] args) {
    ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 4, 1, TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(), new MyRejectedExecutionHandler());
    for (int i = 1; i <= 15; i++) {
        executor.execute(() -> {
            System.out.println(Thread.currentThread().getName() + " 执行!");
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
    }
}

这个例子中,创建了一个大小为2-4的线程池,使用了ArrayBlockingQueue作为任务队列。在创建线程池时我们传入了自定义的MyRejectedExecutionHandler,它是RejectedExecutionHandler接口的实现类,用于处理线程池在满负荷运作时拒绝新任务的情况。

public class MyRejectedExecutionHandler implements RejectedExecutionHandler {
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        System.out.println("线程池已满,拒绝执行 " + r.toString());
    }
}

这个拒绝策略很简单,只是在控制台输出一行日志。在主函数中,我们提交了15个任务到线程池,虽然线程池只能处理4个任务,但是我们不会收到RejectedExecutionException异常,因为我们设置了自定义的拒绝策略。

例子2:定时执行任务

public static void main(String[] args) throws InterruptedException {
    ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
    executor.scheduleAtFixedRate(() -> {
        System.out.println(Thread.currentThread().getName() + " 执行!");
    }, 0, 1, TimeUnit.SECONDS);
    TimeUnit.SECONDS.sleep(5);
    executor.shutdown();
}

在这个例子中,我们使用了ScheduledThreadPoolExecutor来创建定时任务。在构造函数中,我们传入一个1,表示只有一个线程在执行任务,并且使用scheduleAtFixedRate方法设置任务的执行周期以及执行初始延迟时间。在这里,任务会每隔1秒钟执行1次。

在主函数中,我们使用TimeUnit.SECONDS.sleep(5)让程序等待5秒钟,然后使用executor.shutdown()关闭线程池。

通过这两个例子,我们可以看到使用Java线程池能够极大的提高代码的可伸缩性和性能,并且灵活定制线程池的各种参数,可以满足各种复杂的业务场景。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java ThreadPoolExecutor 并发调用实例详解 - Python技术站

(0)
上一篇 2023年5月16日
下一篇 2023年5月16日

相关文章

  • Java 实现并发的几种方式小结

    Java 实现并发的几种方式小结 在 Java 中,实现并发有多种方式,本文将对其中的几种方式进行介绍及总结。 使用 Thread 类实现并发 Thread 类是 Java 中用于实现多线程的基类。使用 Thread 类实现并发的方式是创建一个继承 Thread 类的子类,子类中重写 run() 方法,run() 方法中定义需要执行的代码。 示例代码: pu…

    多线程 2023年5月16日
    00
  • Redis瞬时高并发秒杀方案总结

    Redis瞬时高并发秒杀方案总结 背景 在高并发场景下,秒杀活动通常是让系统压力最大的操作之一。传统的数据库方式往往无法应对高并发,导致系统崩溃。而使用Redis可以有效地解决这个问题。 Redis的优势 Redis是一个基于内存的高性能缓存数据库,对于高并发的应用场景非常适用。Redis的优势主要有以下几点: 高性能:Redis以内存为存储介质,比传统的基…

    多线程 2023年5月16日
    00
  • Java多线程并发synchronized 关键字

    Java多线程并发synchronized 关键字攻略 什么是synchronized synchronized是Java中用于控制并发访问的关键字,它能够确保程序在执行synchronized代码块或方法时,同一时刻只有一个线程可以进入,其他线程必须等待,直到当前线程执行完毕。 如何使用synchronized 在Java中,synchronized可以用…

    多线程 2023年5月16日
    00
  • Python中的并发编程实例

    关于Python中的并发编程实例,可以分为如下步骤进行: 步骤一:什么是并发编程? 并发编程简单来说就是在同一时间内处理多个任务,让程序更加高效、快速的运行。Python中有多种并发编程解决方案,例如线程、协程、多进程等。 步骤二:Python中的常用并发编程模块 Python语言自带的标准库中已经提供了一些常见的并发编程模块,例如threading、mul…

    多线程 2023年5月16日
    00
  • Java并发编程变量可见性避免指令重排使用详解

    Java并发编程变量可见性避免指令重排使用详解 什么是Java并发编程的变量可见性 Java并发编程中典型问题之一是变量可见性。在多线程环境下,一个线程修改的变量不一定会立即对另一个线程可见。这是因为每个线程都有它自己的工作内存,并且线程之间不一定立即同步。 例如,当一个线程修改了变量X的值,如果该变量在另一个线程中被使用,那么第二个线程可能会看到第一个线程…

    多线程 2023年5月16日
    00
  • 简单谈谈Java 中的线程的几种状态

    当Java程序启动时,JVM会为主线程分配一个特殊的栈来执行代码。同时,程序可以创建若干个子线程以支持并发执行相应的任务。线程在执行过程中,可以出现以下几种状态: 新建状态(New) 当线程对象创建以后,该线程处于新建状态。此时线程对象已经在内存中了,但是还没有分配系统资源,没有被CPU选中去执行,也没有开始执行线程中的代码。因此,新建状态的线程在内存中的状…

    多线程 2023年5月16日
    00
  • golang 限制同一时间的并发量操作

    下面是详细讲解“golang 限制同一时间的并发量操作”的完整攻略: 前置知识 在了解如何限制同一时间的并发量操作之前,我们需要先了解一些并发编程基础知识,包括 goroutine、channel、sync.WaitGroup 和 sync.Mutex。 goroutine:Go 语言的轻量级线程,可以在多个 goroutine 之间并发执行。 channe…

    多线程 2023年5月16日
    00
  • Go 并发实现协程同步的多种解决方法

    Go 并发实现协程同步的多种解决方法 在 Go 编程中,对于大量协程的并发执行,我们经常需要对它们进行同步控制,以保证协程之间的正确互动和信息传递。本文介绍 Go 实现协程同步的常用方法,包括使用 WaitGroup、channel、Mutex 等。 使用 WaitGroup 举个例子,我们可能需要同时开启多个协程进行图片下载,且需要等所有协程下载完毕才能继…

    多线程 2023年5月16日
    00
合作推广
合作推广
分享本页
返回顶部