Java中线程池的使用

一.为什么要用线程池

 在多个任务的情况下,开启多个线程能提高处理效率.但开的线程数并不是越多越好.线程的创建与销毁需要时间.如果创建时间+销毁时间>执行任务实际这样就很不划算.一个线程默认最大栈大小1M,这个栈空间需要从系统内存中分配.线程过多,会消耗很多的内存.操作系统也需要频繁的切换线程上下文,影响性能.线程池的推出,就是为了方便的控制线程数量.

二. 线程池的构造

     1.线程池管理器:用于创建并管理线程池,包括创建线程池,销毁线程池,添加新任务.             

      2.工作线程:线程池中线程,在没有任务时处于等待状态,可以循环的执行任务

      3.任务接口:每个任务必须实现的接口,以供工作线程调度任务的执行

      4.任务队列:用于存放没有处理的任务.

三.线程池的创建

     1.标准的线程池

public void test01(){
    ThreadPoolExecutor poolExecutor =
            new ThreadPoolExecutor(1, 5, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<>(20));
    for (int i = 0; i < 10; i++) {
        poolExecutor.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello ThreadPoll!");
            }
        });
    }
}

   第一个参数是核心线程数,这个在初始化的时候就会创建.

   第二个参数是最大线程数,当达到最大线程数时线程池就开始拒绝接受新任务.

   第三个参数是线程空闲时间,当线程池中的线程(不包含核心线程),处于空闲状态超过这个配置的时间便会被回收.

  第四个参数是线程空闲时间的时间单位

  第五个参数是任务队列,当有任务提交时核心线程又处于忙碌状态时,会先把任务放到队列中.当队列满时来一个任务,会先判断线程池中数量是否大于最大线程数,如果小于最大线程数就会创建一个新的线程.如果线程池中线程数等于了最大线程数(第二个参数)则不再接收新的任务.

参数的配置尤其要注意队列大小的设置,如果不设队列的限定值,则是无界队列,这时线程池中最大线程数为核心线程数,并没有更好的提高效率.在使用过程中队列的大小要根据实际情况进配置.

 2.线程池的其它创建方式

  Executors.newFixedThreadPool(int count);  创建一个固定大小,任务队列容量无界的线程池.核心线程数=最大线程数

Executors.newCachedThreadPool(); 创建的是一个大小无界的缓冲线程池,任务加入池中,如果池中有空闲线程,则用空闲线程,如果无空闲线程则创建新的线程执行.池中的线程空闲超时时间为60秒.线程数随任务的多少变化.池的核心线程数=0,最大线程数等于int的最大值

Executors.newSingleThreadExecutor();只有一个线程来执行无界任务队列的单一线程池.

 

      

<think>好的,我现在需要帮助用户找到关于Java中线程池和PriorityBlockingQueue的使用教程,并提供示例代码。首先,我需要回忆用户提供的引用内容,看看是否有相关的信息。根据引用4,PriorityBlockingQueue是一个基于堆结构的无界优先级阻塞队列,元素必须实现Comparable接口或者自定义Comparator。而引用3和5提到了线程池的创建和使用,特别是ScheduledThreadPoolExecutor和线程池的基本概念。 用户的需求是将PriorityBlockingQueue与线程池结合使用,所以需要确定如何在线程池使用这个队列。通常,线程池的构造函数允许传入一个BlockingQueue作为工作队列。例如,ThreadPoolExecutor可以接收PriorityBlockingQueue作为参数,这样任务就会按照优先级执行。 接下来,我需要确保示例代码的正确性。首先,创建一个实现Runnable接口的任务类,并实现Comparable接口以便PriorityBlockingQueue能够根据优先级排序。然后,创建线程池时指定使用PriorityBlockingQueue作为工作队列。需要注意的是,线程池的核心参数如核心线程数、最大线程数等需要合理设置,这里可能需要根据具体情况调整。 另外,引用4提到PriorityBlockingQueue在队列满时会自动扩容,所以不用担心队列容量问题。同时,任务提交到线程池后,会根据优先级被处理,高优先级的任务先执行。 还需要验证是否需要自定义Comparator,或者是否任务类本身实现Comparable即可。根据引用4,元素必须实现Comparator或者在创建队列时指定,因此在示例中,可以让任务类实现Comparable接口,或者在创建队列时传入Comparator。 最后,确保代码示例符合Java语法,比如正确使用泛型、线程池的创建方式等。可能还需要解释代码的关键部分,帮助用户理解如何使用和调整参数。</think>### Java PriorityBlockingQueue线程池使用教程 #### 一、核心特性 1. **无界队列**:队列会自动扩容(默认初始容量11)[^4] 2. **优先级排序**:基于堆结构实现,元素需实现`Comparable`或自定义`Comparator` 3. **线程安全**:内部使用ReentrantLock保证并发安全 #### 二、实现步骤 1. **创建任务类**(需实现比较接口) ```java class PriorityTask implements Runnable, Comparable<PriorityTask> { private final int priority; private final String taskName; public PriorityTask(int priority, String taskName) { this.priority = priority; this.taskName = taskName; } @Override public void run() { System.out.println(Thread.currentThread().getName() + " 执行任务:" + taskName + " (优先级:" + priority + ")"); } @Override public int compareTo(PriorityTask o) { return Integer.compare(o.priority, this.priority); // 数值越大优先级越高 } } ``` 2. **创建线程池**(使用PriorityBlockingQueue) ```java // 创建带优先级的线程池 ThreadPoolExecutor executor = new ThreadPoolExecutor( 2, // 核心线程数 4, // 最大线程数 60, // 空闲线程存活时间 TimeUnit.SECONDS, new PriorityBlockingQueue<>() // 使用无界优先级队列 ); // 提交任务示例 executor.execute(new PriorityTask(5, "紧急告警处理")); executor.execute(new PriorityTask(1, "常规日志清理")); executor.execute(new PriorityTask(9, "支付交易处理")); ``` #### 三、关键参数说明 $$ \text{线程池处理流程} = \begin{cases} \text{核心线程数内:立即执行} \\ \text{超过核心数:入优先级队列} \\ \text{队列满且线程数 < 最大线程数:创建新线程} \\ \text{超过最大线程数:触发拒绝策略} \end{cases} $$ #### 四、典型应用场景 1. 金融交易系统(优先处理高价值交易) 2. 任务调度系统(紧急任务优先执行) 3. 实时监控系统(高级别告警优先处理) #### 五、注意事项 1. **内存控制**:虽然队列无界,但需防止任务堆积导致OOM 2. **公平性保障**:长时间高优先级任务可能造成低优先级任务饥饿 3. **比较器实现**:若使用自定义Comparator,需确保线程安全
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值