多线程之线程池newFixedThreadPool

本文介绍如何利用ThreadFactory自定义线程属性,并通过示例展示了如何在创建固定大小的线程池时指定线程名称等配置。

创建固定大小的线程池的时候使用ThreadFactory

public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), threadFactory); }


ThreadFactory的作用:构造一个新 Thread。实现也可能初始化属性、名称、守护程序状态、ThreadGroup 等等。

在写demo的时候,我认为最麻烦的就是,设置循环中创建的线程的join方法。 在没有使用线程池的时候,在循环中调用这个方法都麻烦,要么抛出异常,要么就只有再循环一次来单独设置。 就这个场景而言,使用ThreadFactory来就很简单了。 ——————– 好把,我以为在工厂中,自己调用join方法能行。但是测试过了。视乎没有效果。 那就只能看下用法。场景用途我暂时也不知道了

示例如下:

/**
 * Created by zhuqiang on 2015/8/25 0025.
 */
public class Client {
    public static void main(String[] args) {
//        ThreadPoolExecutor es = (ThreadPoolExecutor) Executors.newFixedThreadPool(3);  //1 该注释代码。和下面为使用工厂的对比。
        ThreadPoolExecutor es = (ThreadPoolExecutor) Executors.newFixedThreadPool(3, new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                Thread thread = new Thread(r);
                thread.setName("xxxx" + thread.getId());  //对新创建的线程做一些操作
                return thread;
            }
        });
        for (int i = 0; i < 10 ; i++) {
            es.execute(new Task(es,"task-"+i));
        }
        es.shutdown();
    }
}
class Task implements  Runnable{
    private  ThreadPoolExecutor es;
    private  String name;

    public Task(ThreadPoolExecutor es, String name) {
        this.es = es;
        this.name = name;
    }

    @Override
    public void run() {
        try {
            long timeout = (long) (Math.random() * 10);
            TimeUnit.SECONDS.sleep(timeout);
            System.out.println(Thread.currentThread().getName() + "...执行完成..task=" + name +"    耗时:" + timeout);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

<think>嗯,用户问的是多线程线程池的区别。我需要先回顾一下这两个概念的基本定义。多线程通常指的是在应用程序中创建多个线程来同时执行不同的任务,而线程池则是一个管理多个线程的机制,根据需要分配任务给这些线程,避免频繁创建和销毁线程的开销。 首先,用户可能对这两个概念有些混淆,或者想了解它们在实际应用中的不同。我需要从几个方面来对比,比如资源管理、性能、适用场景等。比如,多线程直接创建线程,资源消耗大,而线程池可以复用线程,减少开销。另外,线程池有任务队列和管理策略,而多线程需要手动管理线程的生命周期。 接下来,用户可能想知道具体的应用场景。例如,线程池适合任务数量多且短小的情况,而多线程可能适合任务独立且数量较少的情况。需要举一些例子,比如Web服务器处理请求用线程池,而单个后台任务可能用多线程。 还要注意用户可能的误区,比如认为线程池只是简单的线程复用,但实际上它还有更多的管理功能,比如控制并发数、任务调度等。需要明确这些区别,帮助用户理解为何线程池更高效和可靠。 另外,用户可能没有提到但需要补充的是,线程池如何避免资源耗尽的问题,比如通过拒绝策略和队列管理,而多线程如果没有正确控制,可能导致系统资源被大量线程占用,甚至崩溃。 最后,要确保回答结构清晰,分点说明区别,并给出示例代码,帮助用户更直观地理解。同时,相关问题要围绕用户可能的后续疑问,比如线程池配置、任务队列选择、线程安全等,确保覆盖全面。</think>多线程线程池是并发编程中的两种不同实现方式,核心区别在于**资源管理方式**和**任务调度机制**。以下是具体对比: --- ### **1. 定义与核心区别** | **维度** | **多线程(直接创建线程)** | **线程池(ThreadPool)** | |------------------|--------------------------------------------------|--------------------------------------------------| | **实现方式** | 直接通过`new Thread().start()`创建线程并执行任务 | 通过线程池管理线程生命周期,任务提交后由池内线程动态分配执行 | | **资源消耗** | 频繁创建/销毁线程,导致资源浪费(如内存、CPU上下文切换) | 线程复用,减少资源开销 | | **任务调度** | 需手动管理线程同步、优先级、生命周期等 | 自动管理任务队列、线程分配、拒绝策略等 | | **适用场景** | 简单的短期任务或少量并发需求 | 复杂的高并发任务(如Web服务器、批量数据处理) | --- ### **2. 代码示例对比** #### **多线程直接创建线程** ```java new Thread(() -> { System.out.println("执行任务1"); }).start(); new Thread(() -> { System.out.println("执行任务2"); }).start(); ``` #### **线程池提交任务** ```java ExecutorService executor = Executors.newFixedThreadPool(5); executor.submit(() -> System.out.println("执行任务1")); executor.submit(() -> System.out.println("执行任务2")); executor.shutdown(); ``` --- ### **3. 关键区别详解** #### **(1)资源管理** - **多线程**: 每次任务都需要创建新线程,频繁的创建/销毁会导致内存和CPU资源浪费,尤其在高并发场景下可能引发`OutOfMemoryError`。 - **线程池**: 通过线程复用机制减少资源开销。例如,核心线程数为5的线程池可复用5个线程处理100个任务。 #### **(2)任务调度控制** - **多线程**: 需手动实现线程同步(如`join()`、`synchronized`)和优先级控制,容易引发死锁或资源竞争。 - **线程池**: 提供任务队列(如`BlockingQueue`)和拒绝策略(如`AbortPolicy`),自动管理任务的排队和执行。 #### **(3)稳定性与扩展性** - **多线程**: 无内置的限流和熔断机制,任务过载时可能直接压垮系统。 - **线程池**: 可通过参数配置实现动态扩容(如`maximumPoolSize`)、任务排队(如`ArrayBlockingQueue`)和拒绝策略(如记录日志或降级处理)。 #### **(4)适用场景** - **多线程**: 适合任务数量少、执行时间短、无需复杂管理的场景(如单次异步通知)。 - **线程池**: 适合高并发、任务量大、需精细化控制的场景(如HTTP请求处理、定时任务调度)。 --- ### **4. 线程池的优势总结** 1. **降低资源消耗**:通过复用线程减少创建/销毁的开销。 2. **提高响应速度**:任务到达后无需等待线程创建,直接执行。 3. **任务统一管理**:支持任务队列、拒绝策略、线程监控等。 4. **避免资源耗尽**:通过队列和拒绝策略防止系统过载。 --- ### **5. 典型反例:直接使用多线程的风险** ```java for (int i = 0; i < 10000; i++) { new Thread(() -> { // 处理任务 }).start(); } ``` - **风险**: - 线程数超过系统承载能力,导致内存溢出(`OutOfMemoryError`)。 - CPU频繁切换线程上下文,性能急剧下降。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值