Java多线程 自定义线程池详情

Java多线程 自定义线程池详情

什么是线程池?

线程池是一种线程复用的机制,用于管理与分配线程。在程序中,线程池预先为一组可重用的线程分配了一定数量的线程。这些线程对于一定数量的任务是可用的。一旦指定了任务,就将任务放入队列中排队等待线程。一旦有可用的线程,它就会从队列中取出一个任务并处理它。

JDK内置的线程池

在JDK中,可以使用Executors类创建线程池,有以下几种类型的线程池:

  • 固定大小线程池
  • 无限大小线程池
  • 单线程线程池
  • 带缓存的线程池

固定大小线程池

固定大小线程池创建一个线程池,它的大小是固定的。线程池中线程的数量不会发生变化,即使有空闲的线程,线程也不会被重新调整大小。

ExecutorService executorService = Executors.newFixedThreadPool(5);

无限大小线程池

无限大小线程池创建一个无限数量的线程池。它的线程数量会根据需要不断地增加,但是在请求的线程数量很多的情况下,可能会降低系统的性能。

ExecutorService executorService = Executors.newCachedThreadPool();

单线程线程池

单线程线程池创建一个只有一个线程的线程池。如果这个线程因为异常退出,那么线程池会再次创建一个新的线程,确保线程池中的线程数量始终为1。

ExecutorService executorService = Executors.newSingleThreadExecutor();

带缓存的线程池

带缓存的线程池与无限大小线程池类似,但线程的生命周期仅限于任务的执行时间。在任务执行完成之后,无用的线程会被回收。

ExecutorService executorService = Executors.newCachedThreadPool();

如何使用自定义线程池?

在使用线程池时,可以通过ThreadPoolExecutor来自定义线程池。下面是一个示例代码:

public class CustomThreadPool {

  public static void main(String[] args) {
    /** 核心线程数为10、最大线程数为20、任务队列容量为100的线程池 */
    ThreadPoolExecutor executor = new ThreadPoolExecutor(
        10,
        20,
        60,
        TimeUnit.SECONDS,
        new LinkedBlockingQueue<>(100));

    /** 提交任务,这里提交了20个任务 */
    for (int i = 0; i < 20; i++) {
      executor.execute(() -> {
        System.out.println("task is running");
        try {
          Thread.sleep(2000);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      });
    }
  }
}

在这个示例中,我们创建了一个线程池,核心线程数为10,最大线程数为20,任务队列容量为100。我们提交了20个任务给线程池执行,每个任务输出一个字符串,并睡眠2秒钟。为了模拟任务执行的时间,我们让线程睡眠2秒钟。

自定义线程池的参数解释

ThreadPoolExecutor构造方法所需要的参数:

  • corePoolSize:核心线程数
  • maximumPoolSize:最大线程数
  • keepAliveTime:线程空余保持时间
  • unit:时间单位
  • workQueue:任务队列

示例说明

一、定时任务线程池

下面这个示例是一个简单的定时任务线程池,其中我们通过“ScheduledThreadPoolExecutor”创建了一个定时任务线程池。这个线程池内部由3个线程来处理任务。这里我通过scheduleAtFixedRate方法来定时执行任务。指定了延迟启动时间和重复间隔时间,代码如下:

public class ScheduledExecutorTest {

  public static void main(String[] args) {
    ScheduledThreadPoolExecutor scheduledThreadPool =
        new ScheduledThreadPoolExecutor(3);

    scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
      @Override
      public void run() {
        System.out.println("scheduledThreadPool is running");
      }
    }, 1, 2, TimeUnit.SECONDS);

    scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
      @Override
      public void run() {
        System.out.println("scheduledThreadPool test is running");
      }
    }, 1, 3, TimeUnit.SECONDS);
  }
}

在这个示例中,我们用ScheduledThreadPoolExecutor创建了一个定时任务线程池,内部由3个线程来处理任务。通过scheduleAtFixedRate方法来定时执行任务。这个方法的第一个参数是一个Runnable对象,它的run方法将被定时执行。第二个参数指定了延迟启动时间,第三个参数指定了重复间隔时间,第四个参数指定了时间单位。

二、生产者-消费者线程池

下面这个示例是一个生产者-消费者模式的线程池。这个线程池内部有两种类型的线程,一种是生产者线程,另一种是消费者线程。我们使用LinkedBlockingQueue队列来实现生产和消费的数据交换,代码如下:

public class ProducerConsumerPoolTest {

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

    LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>(10);

    ThreadPoolExecutor producerConsumerPool = new ThreadPoolExecutor(
        2,
        4,
        60,
        TimeUnit.SECONDS,
        new LinkedBlockingQueue<>(20));

    Runnable producerRunnable = () -> {
      try {
        while (true) {
          String data = "" + System.currentTimeMillis();
          System.out.println(Thread.currentThread().getName() + ": Producer - " + data);
          queue.put(data);
          Thread.sleep(1000);
        }
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    };

    Runnable consumerRunnable = () -> {
      try {
        while (true) {
          String data = queue.take();
          System.out.println(Thread.currentThread().getName() + ": Consumer - " + data);
          Thread.sleep(2000);
        }
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    };

    producerConsumerPool.execute(producerRunnable);
    producerConsumerPool.execute(consumerRunnable);

    Thread.sleep(15000);

    producerConsumerPool.shutdown();
  }
}

在这个示例中,我们创建了一个ThreadPoolExecutor线程池,内部包含2个生产者线程和2个消费者线程。生产者线程是不停地往队列中加入数据,而消费者线程不停地获取队列中的数据。

总结

线程池是一种多线程处理机制,通过预先为可重复使用的线程分配线程数量,可以在运行程序时减少实例化和销毁线程的过程。

在JDK中,有4种内置的线程池类型:固定大小线程池、无限大小线程池、单线程池、带缓存的线程池。另外,我们还可以使用ThreadPoolExecutor实现自定义的线程池。

无论使用内置的线程池还是自定义线程池,对线程池的大小和任务队列的容量都要能够正确地评估,在实际应用中,需要根据应用的负载来决定线程池的大小和任务队列的容量,以实现最佳的性能。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java多线程 自定义线程池详情 - Python技术站

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

相关文章

  • Java实现多线程同步五种方法详解

    Java实现多线程同步五种方法详解 什么是多线程同步 在多线程编程中,多个线程访问相同的共享数据时,可能会导致数据异常,因此需要实现多线程同步,以保证数据的正确性。多线程同步的基本思路是,在一个线程访问共享数据时,其他线程不能访问该数据,待该线程访问完毕后,其他线程才能访问该数据。 实现多线程同步的五种方法 Java实现多线程同步的方法较多,下面列举了常用的…

    多线程 2023年5月17日
    00
  • java web在高并发和分布式下实现订单号生成唯一的解决方案

    一、问题背景在高并发和分布式环境下,如果订单号生成不唯一,会涉及到多个用户可能会拥有相同的订单号,这会引发一系列的问题,如数据错误、订单混乱等,导致严重影响客户体验。 二、解决方案使用java web技术生成唯一的订单号,可以采用以下两种方案: 1.使用时间戳和随机数生成订单号订单号通常是由一定位数的时间戳和一定位数的随机数组成,可以使用系统的时间戳加上一个…

    多线程 2023年5月16日
    00
  • Python多线程threading join和守护线程setDeamon原理详解

    Python多线程threading join和守护线程setDeamon原理详解 简介 Python多线程是Python独特的功能之一,可以使程序在同一时间内执行多个并行任务。Python的线程模块提供了两个方法join()和setDaemon(),用于控制线程的行为。本文将详细介绍这两个方法的原理及使用方法。 join()方法 join()方法用于等待一…

    多线程 2023年5月17日
    00
  • Kotlin协程Job生命周期结构化并发详解

    下面是”Kotlin协程Job生命周期结构化并发详解”的完整攻略: Kotlin协程Job生命周期结构化并发详解 概述 Kotlin协程是一种非阻塞式的并发处理机制,它可以极大地简化并发编程。其中一个核心概念就是协程的Job,Job代表了协程的执行任务。在实际使用中,Job可以用来管理和控制协程的生命周期以及取消协程的执行。 本文将详细讲解Kotlin协程J…

    多线程 2023年5月17日
    00
  • Python并发:多线程与多进程的详解

    Python并发:多线程与多进程的详解 一、概述 在Python中进行并发编程可以使用多线程和多进程,两者都可以利用多核CPU提高程序的性能。多线程主要用于IO密集型任务,多进程则适用于CPU密集型任务。 二、多线程 1. 创建线程 在Python中创建线程可以使用threading库,具体步骤如下: import threading def func():…

    多线程 2023年5月16日
    00
  • Python2.7实现多进程下开发多线程示例

    Python2.7实现多进程下开发多线程示例的完整攻略如下: 1.多进程下开发多线程的原理 在Python中,多线程本质上还是单线程,因为CPython解释器存在GIL(全局锁)机制,但是多线程可以充分利用多核CPU的性能。而多进程则是真正的并行,但是相比多线程会更加消耗系统资源,因此在实际应用中需要根据具体情况进行选择。 多进程下开发多线程,其原理是在每个…

    多线程 2023年5月17日
    00
  • python的多线程原来可以这样解

    下面是详细讲解“Python的多线程原来可以这样解”的完整攻略。 什么是多线程? 多线程是指一个进程(程序)中包含多个并发执行的流,每一个流都称为一个线程(Thread),多线程可以将程序中的计算密集型和I/O密集型工作分别交给不同的线程负责,从而提高程序的并发性和效率。 Python中的多线程 Python中的多线程是通过操作系统的线程实现的,Python…

    多线程 2023年5月17日
    00
  • Java并发编程之原子操作类详情

    Java并发编程之原子操作类详情 Java中的原子操作类提供了一种线程安全的方式来处理共享变量。它们能够保证多个线程同时修改变量时不会导致数据竞争。 原子操作类的使用 Java中有几个原子操作类,包括AtomicBoolean、AtomicInteger、AtomicLong和AtomicReference。以下是每个类的简短描述: AtomicBoolea…

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