Java并发线程之线程池的知识总结

Java并发线程之线程池的知识总结

线程池的概念

线程池是一种线程使用模式。线程池中包含了一组线程,线程池可以用来控制创建线程的数量和频率,降低了系统资源消耗率。当有新任务需要执行时,可以直接使用已经存在线程,而不是重新创建新的线程。

线程池的用途

线程池的主要作用是:
* 重用线程
* 控制线程数量,避免线程数量过多,导致系统资源的消耗和浪费
* 提高线程的创建、销毁效率

线程池的实现

Java中的线程池是通过Executor框架实现的。 Executor框架提供了一个线程池的标准接口,具体实现由ThreadPoolExecutor类实现。

ThreadPoolExecutor类的构造方法

ThreadPoolExecutor有多个构造方法,这里简单介绍最常用的一个构造方法:

public ThreadPoolExecutor(int corePoolSize, //线程池中核心线程的数量
                          int maximumPoolSize, //线程池中最大线程数量
                          long keepAliveTime, //非核心线程的空闲时间超时,超时就会被销毁
                          TimeUnit unit,    //keepAliveTime的时间单位,通常设置为秒或者毫秒
                          BlockingQueue<Runnable> workQueue, //线程池中缓存任务的队列
                          ThreadFactory threadFactory,  //线程工厂,用于创建新的线程
                          RejectedExecutionHandler handler) //拒绝策略,当任务添加到线程池失败后的处理方法

线程池的参数介绍

corePoolSize

表示线程池中的核心线程数量。当新任务添加到线程池中时,如果当前运行的线程数小于corePoolSize,那么就创建新的线程来处理请求。如果当前运行的线程数大于或等于corePoolSize,则把任务添加到线程池的工作队列中去。

maximumPoolSize

表示线程池中最大线程数量。当缓存队列满了之后,如果还有新的任务要处理,则会创建新的线程去处理新的任务。但是创建线程数不能超过maximumPoolSize。如果当前运行的线程数已经达到maximumPoolSize,那么就会根据拒绝策略RejectedExecutionHandler来决定如何处理新的任务。

keepAliveTime

表示非核心线程的空闲时间超时,超时就会被销毁。这里的非核心线程是指当前运行的线程数量大于corePoolSize的线程。

unit

表示keepAliveTime的时间单位,通常设置为秒或者毫秒。

workQueue

表示线程池中缓存任务的队列。当新任务添加到线程池中时,如果当前运行的线程数已经达到corePoolSize,那么新的任务就会被添加到workQueue队列中去。

threadFactory

表示创建线程的工厂,用于创建新的线程。

handler

表示拒绝策略,当任务添加到线程池失败后的处理方法。Java提供了4种拒绝策略:
* AbortPolicy(终止策略):如果无法处理新请求,则快速失败并抛出RejectedExecutionException异常。
* CallerRunsPolicy(调用者策略):调用提交任务的线程来处理该任务。
* DiscardOldestPolicy(丢弃旧任务策略):丢弃队列中等待最久的任务,并将当前任务加入队列中。
* DiscardPolicy(丢弃策略):丢弃无法处理的任务。

线程池的示例

下面是一个简单的线程池示例,展示了如何使用线程池:

public class ThreadPoolExample {

    public static void main(String[] args) {

        // 创建线程池
        ExecutorService executorService =
                new ThreadPoolExecutor(2, // 核心线程数为2
                        5, // 最大线程数为5
                        100, // 超时时间为100毫秒
                        TimeUnit.MILLISECONDS,
                        new LinkedBlockingQueue<>(10), // 缓冲队列的大小为10
                        Executors.defaultThreadFactory(),
                        new ThreadPoolExecutor.AbortPolicy()); // 线程池满了后,抛出异常

        // 执行10个任务
        for (int i = 0; i < 10; i++) {
            executorService.execute(new Task(i));
        }

        // 关闭线程池
        executorService.shutdown();
    }

    static class Task implements Runnable {
        private int taskId;

        public Task(int taskId) {
            this.taskId = taskId;
        }

        @Override
        public void run() {
            System.out.println("Task " + taskId + " is running on " + Thread.currentThread().getName());
        }
    }
}

上述示例代码中,通过ThreadPoolExecutor类创建一个线程池executorService,并设置了线程池的核心线程数为2,最大线程数为5,超时时间为100毫秒,缓冲队列的大小为10,拒绝策略为线程池满了后,抛出异常。

然后,执行10个任务,每个任务都是一个Task对象,打印任务编号和运行的线程名。

自定义线程池

除了使用ThreadPoolExecutor提供的构造方法创建线程池外,也可以通过自定义方式来创建线程池,从而满足特定的业务需求,例如使用特定的拒绝策略或使用特定的队列。

下面是一个自定义线程池的示例:

public class CustomThreadPool {

    public static void main(String[] args) {

        // 创建自定义线程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                1, // corePoolSize
                2, // maximumPoolSize
                60, // keepAliveTime
                TimeUnit.SECONDS, // 时间单位
                new ArrayBlockingQueue<>(3), // 队列容量
                Executors.defaultThreadFactory(), // 线程工厂
                new ThreadPoolExecutor.CallerRunsPolicy()); // 拒绝策略

        for (int i = 0; i < 5; i++) {
            try {
                // 添加任务到线程池
                executor.execute(new Task(i));
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }

        // 关闭线程池
        executor.shutdown();
    }

    static class Task implements Runnable {
        private int taskId;

        public Task(int taskId) {
            this.taskId = taskId;
        }

        @Override
        public void run() {
            try {
                System.out.println("Task " + taskId + " is running on " + Thread.currentThread().getName());
                Thread.sleep(3000);
                System.out.println("Task " + taskId + " is completed.");
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }
}

上述示例代码中,通过ThreadPoolExecutor类创建线程池executor,并自定义了核心线程数为1,最大线程数为2,超时时间为60秒,队列容量为3,线程工厂使用默认,拒绝策略为CallerRunsPolicy,即调用提交任务的线程来处理该任务。

然后,通过for循环将5个任务添加到线程池executor中;每个任务都是一个Task对象,打印任务编号和运行的线程名。

最后,关闭线程池executor。由于自定义的线程池是异步的,因此可能会有一些任务尚未完成,但是当主线程结束时,所有任务也会被结束。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java并发线程之线程池的知识总结 - Python技术站

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

相关文章

  • C++11学习之多线程的支持详解

    C++11学习之多线程的支持详解 在C++11标准中,多线程支持成为了一个正式的标准库,并引入了一些新的概念和类型,如线程、互斥锁、条件变量等,以及一些用于控制线程行为的函数和类。 下面我们来详细讲解多线程的支持。 线程 在线程头文件<thread>中定义了线程类std::thread,用于创建和控制线程。线程类的构造函数接收一个可调用对象,并执…

    多线程 2023年5月17日
    00
  • Java多线程之并发编程的核心AQS详解

    Java多线程之并发编程的核心AQS详解 什么是AQS AQS,即AbstractQueuedSynchronizer,是Java多线程并发包(java.util.concurrent)中的一个核心组件,用于构建锁和其他同步工具的基础框架。 AQS 中提供了一些基本的同步状态管理功能,包括获取和释放锁、管理同步状态、阻塞线程等。AQS 的一个重要特性是可以通…

    多线程 2023年5月16日
    00
  • 关于golang高并发的实现与注意事项说明

    关于golang高并发的实现与注意事项说明 Go语言(Golang)因其高并发性能而备受推崇,这也是Go语言最为突出的核心竞争力之一。在使用Go语言进行高并发开发的过程中,有一些需要注意的问题。本文将会介绍如何在Go语言中高效地实现并发以及注意事项说明。 1. Go并发的基本概念 Go语言的并发是基于goroutine(轻量级线程)和channel(管道)两…

    多线程 2023年5月17日
    00
  • java并发数据包Exchanger线程间的数据交换器

    Java并发数据包Exchanger是一个线程间协作的工具,它可以在两个线程之间交换数据。Exchanger能够提供更强大的数据交换功能,它在两个线程之间允许数据交换过程是同步的,也就是说,一个线程在Exchanger调用exchange方法时会一直等待直到另外一个线程也调用exchange方法后才会继续进行,否则会一直阻塞。 Exchanger通过一对线程…

    多线程 2023年5月17日
    00
  • 设置IIS Express并发数

    接下来我将为你详细讲解如何设置IIS Express并发数。首先,我们需要了解一些基本的概念。 什么是IIS Express IIS Express是IIS(Internet Information Services)的轻量级版本,它通常用于本地开发和测试网站。与IIS相比,IIS Express具有更小的安装包大小和更快的启动速度。 并发数是什么 并发数是…

    多线程 2023年5月16日
    00
  • JS模拟多线程

    JS 官网明确表示 JavaScript 是一种单线程语言,这意味着 JavaScript 在同一时刻只能执行一个任务。然而,有时候我们需要在 JavaScript 中模拟多个线程,以实现异步并发执行任务的目的。下面是实现 JS 模拟多线程的完整攻略。 使用 Web Workers Web Workers 是一种在 JavaScript 中实现多线程的机制,…

    多线程 2023年5月17日
    00
  • Java多线程之搞定最后一公里详解

    Java多线程之搞定最后一公里详解 简介 多线程是Java重要的特性之一,它可以使程序变得更加高效和快速,提升用户体验。对于Java开发者来说,不了解多线程的相关概念和技术点就无法达到高超的开发水平。本篇文章主要讲解Java多线程的最后一公里,即如何处理并发的关键问题。 如何处理并发关键问题 1. 竞态条件 竞态条件是多线程编程中最常见的问题之一。它所指的是…

    多线程 2023年5月17日
    00
  • Java Semaphore实现高并发场景下的流量控制

    Java Semaphore实现高并发场景下的流量控制 Semaphore是Java Concurrency API中一个用于实现流量控制的工具类。它可以控制同一时间请求某项资源的线程数量,以达到限流的效果。本文将详细介绍Semaphore的用法以及如何在高并发场景下使用它进行流量控制。 Semaphore的使用 Semaphore的创建: Semaphor…

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