Java线程池的使用方法

yizhihongxing

下面就是Java线程池的使用攻略。

什么是线程池

线程池是多线程编程的一种技术,它是一种旨在优化线程资源使用和管理的实现方式。它重用现有线程来执行任务,因此它可以大大减少线程的创建和销毁的开销。同时,它可以有效地控制并发,避免因线程过多导致CPU过度切换,从而提高系统性能和稳定性。

在Java中,线程池是通过java.util.concurrent包实现的。实际上,Java线程池就是一个线程池的管理器,它维护一个线程池,其中的线程可以执行任何实现了Runnable接口的对象。

如何使用线程池

Java线程池的使用过程包括以下几个步骤:

  1. 创建一个线程池对象

线程池的创建有两种方式:

// 使用 Executors 来创建线程池
ExecutorService executorService = Executors.newFixedThreadPool(10);

// 使用 ThreadPoolExecutor 来创建线程池
ThreadPoolExecutor executor = new ThreadPoolExecutor(
    5,          // 核心线程数
    10,         // 最大线程数
    200,        // 线程空闲时的存活时间
    TimeUnit.MILLISECONDS, // 存活时间的时间单位
    new ArrayBlockingQueue<Runnable>(5), // 任务队列
    new ThreadPoolExecutor.CallerRunsPolicy()  // 拒绝策略
);

上面的示例代码中,第一种方式使用了Executors工厂类的静态方法来创建线程池;第二种方式则是手动创建ThreadPoolExecutor对象,并对其进行一些配置。

  1. 提交任务到线程池

将任务提交到线程池中,线程池会从池中的线程中选择一个来执行该任务。

executorService.execute(new Runnable() {
    @Override
    public void run() {
        // do something
    }
});

上面的示例代码中,通过执行execute()方法将Runnable对象提交给线程池。

  1. 关闭线程池

当不再需要使用线程池时,可以将其关闭以释放资源。

executorService.shutdown();

上面的示例代码中,通过shutdown()方法来关闭线程池。

线程池中的参数

Java线程池包含多个参数,下面是其中一些关键的参数。

  1. 核心线程数

线程池能够同时执行的最大线程数。在没有任务执行时,线程池中保持的线程数。

  1. 最大线程数

线程池能够容纳的最大线程数。当核心线程数达到最大值时,新来的任务会被放在任务队列中等待执行。如果当前任务队列已满,那么新来的任务将创建新线程执行。当最大线程数也到达上限时,则会根据拒绝策略来处理超过最大线程数限制的任务。

  1. 线程的存活时间

当线程空闲时,即没有任务可执行时,它会存活一段时间并保持其线程的状态。存活时间可以指定,如果达到存活时间还没有任务可执行,则该线程会被杀死。

  1. 任务队列

任务队列是一个FIFO队列,用于存放等待执行的任务。如果有新的任务需要执行,但是当前线程数已经达到了最大值,那么它将被加入等待队列。当线程池中有空闲的线程时,它将从该队列中取出待执行的任务。任务队列可以是有界队列,也可以是无界队列。有界队列有数量上限,超过数量上限后再添加任务时,任务将被拒绝。

  1. 拒绝策略

当线程池中的线程数已达到最大值,并且队列也已满时,新来的任务就会被拒绝。此时就需要一个拒绝策略来处理这些被拒绝的任务。Java提供了4种预先定义的拒绝策略:

  • AbortPolicy:直接丢弃任务,并抛出RejectedExecutionException异常。
  • CallerRunsPolicy:使用提交任务的线程去执行该任务。如果提交任务的线程池已经被销毁,则直接丢弃任务。
  • DiscardOldestPolicy:丢弃最早加入等待队列的任务,然后将新任务加入队列。
  • DiscardPolicy:丢弃任务,不做任何处理。

示例代码

下面是一个使用Java线程池的示例代码,用于计算一个数组中所有元素的和。

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

public class ThreadPoolDemo {

    public static void main(String[] args) {
        // 创建一个固定大小的线程池,大小为5
        ExecutorService executor = Executors.newFixedThreadPool(5);

        // 创建一个包含30个元素的数组
        int[] array = new int[30];
        for (int i = 0; i < array.length; i++) {
            array[i] = i + 1;
        }

        // 计算所有元素的和
        int sum = 0;
        for (int i = 0; i < array.length; i++) {
            int value = array[i];

            // 提交任务到线程池
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    sum += value;
                }
            });
        }

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

        // 等待线程池中的任务全部执行结束
        while (!executor.isTerminated()) {
            Thread.yield();
        }

        // 输出所有元素的和
        System.out.println("sum = " + sum);
    }
}

上面的代码中,使用newFixedThreadPool()方法创建一个固定大小的线程池,大小为5。然后创建一个包含30个元素的数组,随后将每个元素通过execute()方法提交给线程池中的线程并计算元素的和。最后关闭线程池并等待其执行完所有任务,输出所有元素的和。

另外,为了说明线程池中的参数,下面是一个更加详细的示例代码:

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPoolDemo {

    public static void main(String[] args) {
        // 创建一个大小为5的核心线程池,最大线程数为10,线程存活时间200毫秒,使用有界队列,拒绝策略是CallerRunsPolicy
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                5,          // 核心线程数
                10,         // 最大线程数
                200,        // 线程空闲时的存活时间
                TimeUnit.MILLISECONDS, // 存活时间的时间单位
                new ArrayBlockingQueue<Runnable>(5), // 任务队列
                new ThreadPoolExecutor.CallerRunsPolicy()  // 拒绝策略
        );

        // 提交10个任务给线程池
        for (int i = 0; i < 10; i++) {
            final int taskId = i;
            Runnable task = new Runnable() {
                @Override
                public void run() {
                    try {
                        System.out.println("start task " + taskId);

                        // 任务执行2秒,模拟耗时操作
                        Thread.sleep(2000);

                        System.out.println("end task " + taskId);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };
            executor.submit(task);
        }

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

上面的代码中,手动创建了一个角色线程池,大小为5,最大线程数为10,线程存活时间为200毫秒,使用有界队列。然后提交了10个任务,当线程池的多个线程同时执行任务时,可以很清楚地看到它们的执行过程。最后关闭了线程池。

希望这篇攻略对Java线程池的使用方式有所帮助。

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

(0)
上一篇 2023年4月19日
下一篇 2023年4月19日

相关文章

  • Java的数据类型和变量

    Java数据类型 Java支持8种基本数据类型,它们分别是: byte short int long float double char boolean 这些基本数据类型都有对应的包装类。包装类主要是为了方便基本数据类型的使用,比如说提供了一些实用的静态方法和常量。 下面我们来详细介绍一下Java的各种数据类型。 1. byte byte数据类型是一个8位带…

    Java 2023年4月19日
    00
  • JavaList、Set、Map等常用集合的使用方法

    下面是Java中常用的集合类的使用方法及代码示例。 Java集合类 Java集合类是一组数据结构的实现,用于存储和操作一组对象。在Java中有许多不同的集合类,其中最常用的有List、Set、Map等,下面我们逐一介绍它们的使用方法。 List List是一个有序的集合,可以重复地存储多个元素,每个元素都有一个对应的索引。Java提供了许多不同的List实现…

    Java 2023年4月19日
    00
  • 配置Java环境变量

    配置Java环境变量是Java软件开发的必备步骤。下面详细讲解在Windows系统下配置Java环境变量的方法: 下载Java Development Kit(JDK)并安装 首先需要下载Java Development Kit(JDK),下载地址为:https://www.oracle.com/java/technologies/javase-downlo…

    Java 2023年4月19日
    00
  • Java的控制语句

    控制语句是Java程序中非常重要的概念之一,它们用于控制程序的流程,使程序在执行过程中可以满足特定的条件和需求。Java中的控制语句主要有三种类型:条件语句、循环语句和跳转语句。下面将详细讲解Java中控制语句的使用方法。 条件语句 条件语句用于在程序中根据特定的条件来选择执行的代码。Java中常用的条件语句有if语句、if-else语句、switch语句等…

    Java 2023年4月19日
    00
  • Java之继承和接口的概念

    Java是一种面向对象的编程语言,继承和接口是面向对象语言中重要的概念之一。继承和接口都可以用来扩展类的功能,但它们之间有一些显著的不同。下面将详细介绍Java中继承和接口的概念及其使用方法。 继承 继承是指一个类可以基于另一个类的定义来创建,继承的类称为子类,被继承的类称为父类或超类。子类可以复用父类中的代码,并在此基础上添加新的方法和数据成员。 语法 J…

    Java 2023年4月19日
    00
  • 详解Java的发展历史

    Java是一种广泛使用的编程语言,它诞生于20世纪90年代初期,并经历了多个版本和大量的演变。下面是Java的发展历史: 1991年,Sun Microsystems公司开始了Green计划,旨在开发一种适用于小型设备和家用电器的编程语言,这就是后来的Java。 1995年,Java首次公开发布。这个版本是Java 1.0版,提供了基本的语言结构和Java应…

    Java 2023年4月19日
    00
  • Java的关键字和标识符

    关键字和标识符是Java中的基础概念,它们在编写Java程序中扮演着非常重要的角色。在本篇文章中,我将详细讲解Java关键字和标识符的使用方法,并提供两个具体的代码示例。 Java关键字 Java关键字是Java语言中已经预先定义好的,具有特定含义的单词。这些关键字在Java程序中具有固定的用法,不能被用作变量名或方法名等标识符。在Java中一共有50个关键…

    Java 2023年4月19日
    00
  • Java中类的定义和使用

    Java中类是一种将数据和功能绑定在一起的结构。它包含成员变量和成员方法,成员变量用于表示数据,成员方法用于对数据进行操作。类可以被实例化(实例化即创建对象),从而可以在程序中使用类中定义的方法和变量。 定义一个类 Java中定义一个类的基本语法为: public class ClassName { //成员变量 //构造方法 //成员方法 } 其中,pub…

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