java 线程池的实现方法

Java线程池是一种内部维护一定数量线程,用于处理多个并发任务的机制。使用线程池可以避免不断地创建和销毁线程,从而提高程序的性能和响应速度。本文将详细讲解Java线程池的实现方法,包括线程池的概述、核心参数和实现方式等,并通过示例说明其使用方法。

一、线程池概述

线程池是一种能够提高线程复用率、控制最大并发数、管理线程生命周期的机制。Java线程池中最主要的三个元素是:线程池大小、阻塞队列和拒绝策略。

  1. 线程池大小:线程池中维护的线程数。当线程池中的线程数达到线程池大小时,新的任务将被阻塞。理论上,线程池大小越大,线程并发执行能力越强,但创建线程的开销也会变得越大。

  2. 阻塞队列:当任务数超出线程池大小时,新的任务会先进入阻塞队列中等待执行。常见的阻塞队列包括LinkedBlockingQueue、ArrayBlockingQueue和SynchronousQueue等。

  3. 拒绝策略:当线程池和阻塞队列都已满时,新的任务需要被拒绝。线程池提供了几种拒绝策略,如CallerRunsPolicy、AbortPolicy和DiscardPolicy等。

二、线程池的实现方法

Java线程池的实现方式主要有两种:ThreadPoolExecutor和ScheduledThreadPoolExecutor。前者适用于执行定期或无限期执行的任务,后者适用于执行定期任务的场景。

1. ThreadPoolExecutor

ThreadPoolExecutor是Java线程池的核心实现类。以下是ThreadPoolExecutor的构造方法和核心参数:

ThreadPoolExecutor(int corePoolSize,     // 线程池中维护的线程数量,即核心池大小
                   int maximumPoolSize,  // 线程池中允许的最大线程数
                   long keepAliveTime,   // 非核心线程(闲置线程)的空闲时间
                   TimeUnit unit,        // keepAliveTime的时间单位
                   BlockingQueue<Runnable> workQueue, // 作为任务队列的阻塞队列
                   ThreadFactory threadFactory,        // 生成新线程的工厂
                   RejectedExecutionHandler handler)  // 拒绝策略

以下是两个示例说明:

示例1. 使用ThreadPoolExecutor创建线程池,并提交任务进行执行。

public class ThreadPoolExample {

    private static final int CORE_POOL_SIZE = 2;
    private static final int MAX_POOL_SIZE = 5;
    private static final long KEEP_ALIVE_TIME = 3000;

    private static final ExecutorService executor = new ThreadPoolExecutor(
            CORE_POOL_SIZE, 
            MAX_POOL_SIZE,
            KEEP_ALIVE_TIME,
            TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>(),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.AbortPolicy());

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            final int task = i;
            executor.execute(new Runnable() {
                public void run() {
                    System.out.println(Thread.currentThread().getName() + " Processing Task " + task);
                }
            });
        }
    }
}

解释:在以上示例中,我们创建了一个最多能够容纳5个线程的线程池,使用了默认的线程工厂和拒绝策略。然后,我们提交了10个任务,任务会在被池中的线程执行。由于线程池大小为5,因此前5个任务会在5个不同的线程上并发执行,而后面5个任务会进入阻塞队列等待执行。

示例2. 实现线程池的生命周期方法

public class LifecycleThreadPoolExample {

    private static final int CORE_POOL_SIZE = 2;
    private static final int MAX_POOL_SIZE = 5;
    private static final long KEEP_ALIVE_TIME = 3000;

    private static final ExecutorService executor = new ThreadPoolExecutor(
            CORE_POOL_SIZE, 
            MAX_POOL_SIZE,
            KEEP_ALIVE_TIME,
            TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>(),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.AbortPolicy()){

            @Override
            protected void beforeExecute(Thread t, Runnable r) {
                System.out.println("Before executing thread " + t + " running " + r);
            }

            @Override
            protected void afterExecute(Runnable r, Throwable t) {
                System.out.println("After executing task thread " + Thread.currentThread().getName());
            }

            @Override
            protected void terminated() {
                System.out.println("Thread pool is terminated.");
            }

    };

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            final int task = i;
            executor.execute(new Runnable() {
                public void run() {
                    System.out.println(Thread.currentThread().getName() + " Processing Task " + task);
                }
            });
        }
        executor.shutdown();
    }
}

解释:在以上示例中,我们重写了ThreadPoolExecutor的三个方法beforeExecute、afterExecute和terminated。beforeExecute方法会在线程执行之前被调用,afterExecute方法会在线程执行完毕之后被调用,terminated方法会在线程池完全终止之后被调用。在例子中,我们简单地打印了这些方法的内容,以便理解它们的执行顺序和生命周期。注意例子中的executor.shutdown(),请在使用线程池时注意释放资源。

2. ScheduledThreadPoolExecutor

ScheduledThreadPoolExecutor是一种用于执行定期任务的线程池实现。以下是ScheduledThreadPoolExecutor的构造方法和核心参数:

ScheduledThreadPoolExecutor(int corePoolSize)  // 创建预定大小的线程池

以下是一个示例:

public class ScheduledThreadPoolExample {

    private static final ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(1, Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());

    public static void main(String[] args) {
        executor.scheduleAtFixedRate(new Runnable() {
            public void run() {
                System.out.println("scheduled task");
            }
        }, 0, 1, TimeUnit.SECONDS);
    }
}

解释:在以上示例中,我们创建了一个定期执行任务的线程池,并且通过scheduleAtFixedRate方法设定了任务执行周期为1秒。在任务执行时,每当时间间隔达到规定的周期,任务就会被执行。

三、总结

本文讲解了Java线程池的概述和实现方式,包括ThreadPoolExecutor和ScheduledThreadPoolExecutor两种实现方式,以及如何调整线程池大小、阻塞队列和拒绝策略等核心参数。通过以上两个示例,可以更好地理解和使用Java线程池。在实际开发中,使用线程池可以有效地提高程序的性能和响应速度。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java 线程池的实现方法 - Python技术站

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

相关文章

  • 一小时迅速入门Mybatis之增删查改篇

    一小时迅速入门Mybatis之增删查改篇 Mybatis是一款优秀的ORM框架,其简单易用,功能强大,得到了广大开发者的喜爱。本文将为大家介绍使用Mybatis进行增删查改的完整攻略。 1. 环境准备 Mybatis需要依赖JDBC驱动和数据库连接池,建议使用Maven进行管理。这里我们以MySQL为例,展示如何配置环境。 首先在pom.xml文件中添加以下…

    Java 2023年5月20日
    00
  • springboot整合springsecurity与mybatis-plus的简单实现

    那么让我们来探讨一下如何实现“springboot整合springsecurity与mybatis-plus的简单实现”,包含以下步骤: 1.创建一个springboot项目,添加相关依赖 为了实现该功能,我们首先需要创建一个springboot项目,并添加所需的依赖项。在pom.xml文件中添加以下依赖项: <dependency> <g…

    Java 2023年5月20日
    00
  • mybatis中批量插入的两种方式(高效插入)

    在MyBatis中,批量插入是一种常见的高效插入方式,可以大大减少操作数据库的次数,提高插入效率。本文将详细讲解MyBatis中批量插入的两种方式及使用方法。 使用JDBC批量插入 MyBatis底层封装了JDBC,所以可以使用JDBC的批量操作功能进行批量插入。具体实现步骤如下: 创建数据库表 假设我们要插入的表是user,可以通过以下语句创建表: CRE…

    Java 2023年5月20日
    00
  • Mac下使用charles遇到的问题以及解决办法

    下面是 Mac 下使用 Charles 遇到的问题以及解决办法的攻略: 1. Charles 网络监控工具简介 Charles 是一款用于网络调试和监控的工具,它可以拦截 HTTP 和 HTTPS 的请求和响应,方便开发人员对于应用程序、网站等进行分析和调试。同时,它还提供了网络传输速率、请求次数、响应时间等统计功能,对于网站优化和性能测试也有很大的帮助。 …

    Java 2023年5月23日
    00
  • java ssm框架实现分页功能的示例代码(oracle)

    实现分页功能是很多Web应用程序中的常见需求。在Java SSM框架中,我们可以使用MyBatis分页插件来实现分页功能,下面是针对Oracle数据库的完整攻略。 步骤1:添加相关依赖 要使用MyBatis分页插件,我们需要在项目中添加相关的依赖。以下是Maven配置示例: <dependency> <groupId>com.gith…

    Java 2023年6月15日
    00
  • java对XML文件的解析、节点的增加、删除操作总结

    Java对XML文件的解析、节点的增加、删除操作总结 在Java中,我们常常需要对XML文件进行解析、节点的增加或删除操作。下面将从以下两个方面对这一问题进行分析。 1. XML文件的解析 1.1 使用JDOM进行XML文件解析 JDOM是一款功能强大的Java XML解析库,它可以对XML文档进行解析,并操作XML文档中的元素和属性。其解析XML文档的核心…

    Java 2023年6月15日
    00
  • 从零开始学springboot整合feign跨服务调用的方法

    下面是“从零开始学Spring Boot整合Feign跨服务调用的方法”的完整攻略: 1. 准备工作 1.1 创建两个Spring Boot应用 我们先创建两个Spring Boot应用,一个为服务提供方,一个为服务消费方。 # 服务提供方 $ curl https://start.spring.io/starter.zip \ -d bootVersion…

    Java 2023年5月19日
    00
  • Java获取精确到秒的时间戳方法

    当我们需要获取当前时间的时间戳时,可以使用Java提供的System.currentTimeMillis()方法,该方法返回的是自1970年1月1日零时零分零秒(GMT/UTC)以来的毫秒数,也就是常说的Unix时间戳。但有时候我们需要获取精确到秒的时间戳,可以通过以下两种方式实现。 1. 使用Java 8中的Instant类 Java 8中新增了一个新的日…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部