线程池

140 阅读3分钟

1、线程池了解吗?说一说线程池的几个参数

顾名思义,线程池就是管理一系列线程的资源池。当有任务要处理时,直接从线程池中获取线程来处理,处理完之后线程并不会立即被销毁,而是等待下一个任务。

image.png

线程池有七大参数,我们重点关注corePoolSize、maximumPoolSize、workQueue、handler可以帮助我们更好地理解和优化线程池的性能

  1. corePoolSize:此值是用来初始化线程池中核心线程数,当线程池中线程数<corePoolSize时,系统默认是添加一个任务才创建一个线程池。当线程数=corePoolSize时,新任务会追加到workQueue中。

  2. maximumPoolSize:maximumPoolSize表示允许的最大线程数=(非核心线程数 + 核心线程数),当BlockingQueue也满了,但线程池中总线程数 < maximumPoolSize时候就会再次创建新的线程。

  3. keepAliveTime:非核心线程 = (maximumPoolSize-corePoolSize),非核心线程闲置下来不干活最多存活时间。

  4. unit:线程池中非核心线程保持存活的时间的单位

    • TimeUnit.DAYS;天
    • TimeUnit.HOURS;小时
    • TimeUnit.MINUTES;分钟
    • TimeUnit.SECONDS;秒
    • TimeUnit.MILLISECONDS;毫秒
    • TimeUnit.MICROSECONDS;微秒
    • TimeUnit.NANOSECONDS;纳秒
  5. workQueue:线程池等待队列,维护着等待执行的Runnable对象。当运行当线程数=corePoolSize时,新的任务会被添加到workQueue中,如果workQueue也满了则尝试用非核心线程执行任务,等待队列应该尽量用有界 的。

  6. threadFactory:创建一个新线程时使用的工厂,可以用来设定线程名、是否为daemon线程等等。

  7. handler:corePoolSize、workQueue、maximumPoolSize都不可用的时候执行的饱和策略。

追问1:核心线程数可以过期么?

核心线程数可以过期。在Java中,当线程数大于核心线程数时,线程将进入缓存线程池,空闲5分钟后会过期,线程池会自动销毁。而核心线程数是指线程池中始终保持的最小工作线程数。

以下是一个使用 Java 线程池设置核心线程数的示例代码:

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

public class ThreadPoolExample {
    public static void main(String[] args) {
        int corePoolSize = 2; // 核心线程数
        int maximumPoolSize = 5; // 最大线程数
        long keepAliveTime = 60L; // 空闲线程的存活时间(单位:秒)
        int queueCapacity = Integer.MAX_VALUE; // 任务队列容量

        ExecutorService executorService = Executors.newFixedThreadPool(corePoolSize);

        // 设置线程池参数
        ((ThreadPoolExecutor) executorService).setCorePoolSize(corePoolSize);
        ((ThreadPoolExecutor) executorService).setMaximumPoolSize(maximumPoolSize);
        ((ThreadPoolExecutor) executorService).setKeepAliveTime(keepAliveTime, TimeUnit.SECONDS);
        ((ThreadPoolExecutor) executorService).setQueueCapacity(queueCapacity);

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

        executorService.shutdown();
    }
}

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.");
    }
}

在上述代码中,我们使用了 Executors.newFixedThreadPool(corePoolSize) 方法创建了一个固定大小的为 corePoolSize 的线程池,然后通过 ((ThreadPoolExecutor) executorService).setCorePoolSize(corePoolSize) 方法设置了核心线程数为 corePoolSize。

在上述代码中,使用了以下函数:

  • Executors.newFixedThreadPool(corePoolSize):该函数用于创建一个固定大小为corePoolSize的线程池。
  • executorService.execute(new Task(i)):该函数用于向线程池提交任务。
  • executorService.shutdown():该函数用于关闭线程池。

此外,还使用了 Java 中的 ThreadPoolExecutor 类的一些函数,如 setCorePoolSize()、setMaximumPoolSize()、setKeepAliveTime() 和 setQueueCapacity(),用于设置线程池的参数。

追问2:核心线程都被使用了,有新的任务上传会怎么样

2、线程池的作用

3、如何创建线程池

4、线程池的几种状态

5、线程池原理

6、线程池中有哪些参数可以配置?

7、