线程池中的线程工厂


线程池中的线程工厂

在 Java 中,线程工厂ThreadFactory)用于创建线程,它提供了一种自定义线程创建过程的方式(如设置线程名称、优先级、是否为守护线程等)。

线程工厂通常与线程池结合使用,常见的线程工厂创建和使用方式有以下几种:

1. 自定义实现 ThreadFactory 接口

这是最灵活的方式,通过实现 ThreadFactory 接口的 newThread(Runnable r) 方法,完全自定义线程的创建逻辑。

示例代码:

import java.util.concurrent.ThreadFactory;

public class CustomThreadFactory implements ThreadFactory {
    private int threadCount = 0;
    private String prefix;

    public CustomThreadFactory(String prefix) {
        this.prefix = prefix;
    }

    @Override
    public Thread newThread(Runnable r) {
        // 自定义线程名称(便于调试)
        Thread thread = new Thread(r, prefix + "-thread-" + threadCount++);
        // 设置为非守护线程
        thread.setDaemon(false);
        // 设置优先级(默认5,范围1-10)
        thread.setPriority(Thread.NORM_PRIORITY);
        // 可以添加未捕获异常处理器
        thread.setUncaughtExceptionHandler((t, e) -> {
            System.err.println("线程 " + t.getName() + " 发生异常: " + e.getMessage());
        });
        return thread;
    }

    // 使用示例
    public static void main(String[] args) {
        CustomThreadFactory factory = new CustomThreadFactory("my-thread-pool");
        // 创建线程并执行
        Thread thread = factory.newThread(() -> {
            System.out.println("线程 " + Thread.currentThread().getName() + " 执行中");
        });
        thread.start();
    }
}

2. 使用 JDK 内置的 Executors.defaultThreadFactory()

JDK 提供了默认的线程工厂实现,可通过 Executors 工具类获取。其创建的线程:

  • 属于默认线程组
  • 名称格式为 pool-{池编号}-thread-{线程编号}
  • 非守护线程
  • 优先级为 Thread.NORM_PRIORITY

示例代码:

import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

public class DefaultThreadFactoryExample {
    public static void main(String[] args) {
        // 获取默认线程工厂
        ThreadFactory defaultFactory = Executors.defaultThreadFactory();
        
        // 创建线程并执行
        Thread thread = defaultFactory.newThread(() -> {
            System.out.println("默认线程名称: " + Thread.currentThread().getName());
        });
        thread.start(); // 输出类似:默认线程名称: pool-1-thread-1
    }
}

3. 使用 Guava 库的 ThreadFactoryBuilder

Google Guava 库提供了 ThreadFactoryBuilder 工具类,通过链式调用简化线程工厂的创建,无需手动实现接口。

依赖(Maven)

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>31.1-jre</version>
</dependency>

示例代码:

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.util.concurrent.ThreadFactory;

public class GuavaThreadFactoryExample {
    public static void main(String[] args) {
        // 链式构建线程工厂
        ThreadFactory guavaFactory = new ThreadFactoryBuilder()
                .setNameFormat("guava-thread-%d") // 线程名称格式
                .setDaemon(false) // 非守护线程
                .setPriority(Thread.NORM_PRIORITY) // 优先级
                .setUncaughtExceptionHandler((t, e) -> { // 未捕获异常处理器
                    System.err.println("线程 " + t.getName() + " 异常: " + e.getMessage());
                })
                .build();

        // 使用线程工厂
        Thread thread = guavaFactory.newThread(() -> {
            System.out.println("Guava 线程名称: " + Thread.currentThread().getName());
        });
        thread.start(); // 输出:Guava 线程名称: guava-thread-0
    }
}

4. 使用 Apache Commons Lang 库的 BasicThreadFactory

Apache Commons Lang 库也提供了线程工厂实现 BasicThreadFactory,支持自定义线程属性。

依赖(Maven)

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.12.0</version>
</dependency>

示例代码:

import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import java.util.concurrent.ThreadFactory;

public class CommonsThreadFactoryExample {
    public static void main(String[] args) {
        // 创建线程工厂
        ThreadFactory commonsFactory = new BasicThreadFactory.Builder()
                .namingPattern("commons-thread-%d") // 线程名称格式
                .daemon(false) // 非守护线程
                .priority(Thread.NORM_PRIORITY)
                .uncaughtExceptionHandler((t, e) -> {
                    System.err.println("线程 " + t.getName() + " 异常: " + e.getMessage());
                })
                .build();

        // 使用线程工厂
        Thread thread = commonsFactory.newThread(() -> {
            System.out.println("Commons 线程名称: " + Thread.currentThread().getName());
        });
        thread.start(); // 输出:Commons 线程名称: commons-thread-1
    }
}

5. 在线程池中使用线程工厂

线程工厂最常见的场景是配合线程池(如 ThreadPoolExecutor)使用,用于统一管理线程池中的线程创建。

示例代码:

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

public class ThreadPoolWithFactory {
    public static void main(String[] args) {
        // 自定义线程工厂
        ThreadFactory factory = new CustomThreadFactory("pool-thread");

        // 创建线程池时指定线程工厂
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                2, // 核心线程数
                5, // 最大线程数
                60, TimeUnit.SECONDS, // 空闲线程存活时间
                new LinkedBlockingQueue<>(10), // 任务队列
                factory, // 线程工厂
                new ThreadPoolExecutor.AbortPolicy() // 拒绝策略
        );

        // 提交任务
        executor.submit(() -> {
            System.out.println("线程池中的线程: " + Thread.currentThread().getName());
        });

        executor.shutdown();
    }
}

总结

  • 自定义 ThreadFactory 接口:灵活性最高,适合复杂需求。
  • JDK 内置工厂:简单场景下使用,无需依赖第三方库。
  • Guava/Apache Commons:通过工具类简化配置,适合快速开发。
  • 线程工厂通常与线程池结合使用,用于标准化线程的创建逻辑,便于调试和管理。
知识点
多线程
Mysql