JAVA线程池使用实例

一、JAVA线程池使用

在使用Java多线程时引入线程池技术可以大大提高程序性能。Java提供的线程池相关的类主要有四个:Executor、ExecutorService、ScheduledExecutorService和ThreadPoolExecutor。其中,使用ThreadPoolExecutor类可以对线程池进行灵活的设置,可以很好地适应各种场景。

二、JAVA线程池参数设置

在使用Java线程池时,可以根据实际情况对线程池进行参数设置,以达到最佳的程序性能。线程池的主要参数包括以下几个方面:

1、corePoolSize

核心池大小,即线程池初始化后启动的线程数量。如果当前线程数量小于核心池大小,则新建线程;否则会将任务放入任务队列等待执行。

2、maximumPoolSize

最大线程数量,即线程池中最多同时执行的线程数量。当线程池中已有的线程数大于等于corePoolSize时,新任务到来时会将任务放入任务队列中等待。当任务到来时任务队列已满且当前线程数小于maximumPoolSize,则新建线程执行该任务。当线程数已达到最大线程数且任务队列已满,则会根据所设置的RejectedExecutionHandler进行相应的拒绝处理。

3、keepAliveTime

线程空闲时间,即空闲线程的存活时间。当线程池中线程数量大于corePoolSize时,需要有一定的机制来回收空闲线程,以便于释放系统资源。当空闲时间超过keepAliveTime时,空闲线程将被回收。

4、TimeUnit

空闲时间的时间单位。该项参数以TimeUnit枚举类型传入,可以设置为TimeUnit.SECONDS、TimeUnit.MINUTES、TimeUnit.HOURS等。

5、workQueue

任务队列。当线程池中线程数量达到corePoolSize时,新任务到来会被放入任务队列中。该任务队列可以是SynchronousQueue、LinkedBlockingQueue、ArrayBlockingQueue等各种线程安全队列,也可以根据需要自己实现。

6、threadFactory

线程工厂。用于创建新的线程对象。可以通过ThreadFactoryBuilder来创建一个线程工厂。

7、rejectedExecutionHandler

任务拒绝策略。当线程池中线程数量已达到maximumPoolSize并且任务队列已经满了时,需要有一种机制来处理新到达的任务。主要有四种处理方式:

  • AbortPolicy(默认):直接抛出RejectedExecutionException异常。
  • CallerRunsPolicy:任务由调用线程直接执行。
  • DiscardOldestPolicy:将等待时间最长的任务从队列中移除,将新任务加入队列中。
  • DiscardPolicy:直接丢弃该任务。

三、JAVA创建线程池

Java提供了四个线程池类,分别是:

  • FixedThreadPool
  • CachedThreadPool
  • SingleThreadExecutor
  • ScheduledThreadPool

1、FixedThreadPool

FixedThreadPool固定大小线程池,会一直新建线程直到线程达到线程池的最大大小,线程池中的线程都是活跃的,线程池中线程数量不会超过给定的数量,并且线程都是在空闲状态下等待接收任务,所以线程利用率高。

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue());
}

2、CachedThreadPool

CachedThreadPool线程池的大小会根据执行的任务数量自动扩展和收缩,没有核心线程数,超过60秒空闲的线程被终止并从缓冲池中删除。适用于执行大量短期异步任务的情景。

public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue());
}

3、SingleThreadExecutor

SingleThreadExecutor单线程池中只有一个核心线程,该线程会按先进先出的方式执行任务,所以不需要考虑线程同步的问题。适用于需要排队依次执行任务的情况。

public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue()));
}

4、ScheduledThreadPool

ScheduledThreadPool定长线程池可以定时或周期性地执行任务。适用于需要执行定时任务的情况。

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
    return new ScheduledThreadPoolExecutor(corePoolSize);
}

完整的Java线程池使用实例:

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

public class ThreadPoolTest {

    public static void main(String[] args) throws Exception {

        ExecutorService executorService = Executors.newFixedThreadPool(2);

        executorService.execute(() -> {
            System.out.println("任务1开始执行");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("任务1执行完毕");
        });

        executorService.execute(() -> {
            System.out.println("任务2开始执行");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("任务2执行完毕");
        });

        executorService.execute(() -> {
            System.out.println("任务3开始执行");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("任务3执行完毕");
        });

        executorService.shutdown();
        executorService.awaitTermination(1, TimeUnit.HOURS);

    }

}

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/198629.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝的头像小蓝
上一篇 2024-12-04 10:26
下一篇 2024-12-04 10:26

相关推荐

  • Java JsonPath 效率优化指南

    本篇文章将深入探讨Java JsonPath的效率问题,并提供一些优化方案。 一、JsonPath 简介 JsonPath是一个可用于从JSON数据中获取信息的库。它提供了一种DS…

    编程 2025-04-29
  • java client.getacsresponse 编译报错解决方法

    java client.getacsresponse 编译报错是Java编程过程中常见的错误,常见的原因是代码的语法错误、类库依赖问题和编译环境的配置问题。下面将从多个方面进行分析…

    编程 2025-04-29
  • Java Bean加载过程

    Java Bean加载过程涉及到类加载器、反射机制和Java虚拟机的执行过程。在本文中,将从这三个方面详细阐述Java Bean加载的过程。 一、类加载器 类加载器是Java虚拟机…

    编程 2025-04-29
  • Java腾讯云音视频对接

    本文旨在从多个方面详细阐述Java腾讯云音视频对接,提供完整的代码示例。 一、腾讯云音视频介绍 腾讯云音视频服务(Cloud Tencent Real-Time Communica…

    编程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介绍

    本文将详细介绍Java Milvus SearchParam withoutFields的相关知识和用法。 一、什么是Java Milvus SearchParam without…

    编程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java语言中的一个版本,于2014年3月18日发布。本文将从多个方面对Java 8中某一周的周一进行详细的阐述。 一、数组处理 Java 8新特性之一是Stream…

    编程 2025-04-29
  • Java判断字符串是否存在多个

    本文将从以下几个方面详细阐述如何使用Java判断一个字符串中是否存在多个指定字符: 一、字符串遍历 字符串是Java编程中非常重要的一种数据类型。要判断字符串中是否存在多个指定字符…

    编程 2025-04-29
  • Python生成随机数的应用和实例

    本文将向您介绍如何使用Python生成50个60到100之间的随机数,并将列举使用随机数的几个实际应用场景。 一、生成随机数的代码示例 import random # 生成50个6…

    编程 2025-04-29
  • VSCode为什么无法运行Java

    解答:VSCode无法运行Java是因为默认情况下,VSCode并没有集成Java运行环境,需要手动添加Java运行环境或安装相关插件才能实现Java代码的编写、调试和运行。 一、…

    编程 2025-04-29
  • Java任务下发回滚系统的设计与实现

    本文将介绍一个Java任务下发回滚系统的设计与实现。该系统可以用于执行复杂的任务,包括可回滚的任务,及时恢复任务失败前的状态。系统使用Java语言进行开发,可以支持多种类型的任务。…

    编程 2025-04-29

发表回复

登录后才能评论