多线程-线程池(一分钟快速了解)

目录

1.什么是线程池

2.标准库中的线程池

 2.1各个参数什么意思

  int corePoolSize:

   int maximumPoolSize:

   keepAliveTime:

  BlockingQueue workQueue:

   ThradFactory  threadFactory  :线程工厂

 RejectedExecutionHandler handler:(面试可能会问)

3.实现一个线程池


1.什么是线程池

    线程池是一种管理和复用线程的机制。它通过预先创建一组线程并维护它们的生命周期,以便在需要时重复使用这些线程,可以减少线程创建和销毁的开销。

为什么要用线程池呢

        在我们使用多线程进行开发编程的时候,使用多线程确实可以进行并发编程,但是频繁的创建和销毁线程会消耗很多的资源,开销较大。所以我们引入线程池,将需要用的线程,在线程池中准备好,用的时候从线程池中拿,用完又放回到线程池中。这样就可以减小开销。

2.标准库中的线程池

     在标准库中我们用ThreadPoolExecutor类来表示线程池。ThreadPoolExecutor 提供了更多的可选参数, 可以进⼀步细化线程池⾏为的设定.

 2.1各个参数什么意思

  int corePoolSize

        核心线程数。就像在一家公司里的正式员工,。当你被录用了后,就不会被辞退。对公司来说很重要。核心线程数也是一样,在一个进程里是非常重要的。

   int maximumPoolSize

最大线程数。就像是一家公司里的正式员工+实习生。实习生⼀段时间不⼲活, 就被辞退。

   keepAliveTime:

       保持存活时间。就像实习生允许的空闲时间.如果实习生空闲时间超过这个时间就会被辞退。在线程里就表示线程空闲的时间。超过这个时间就会被销毁。

  BlockingQueue<Runnable> workQueue

  和定时器类似,线程池中可以持有很多任务。以Runnable为对象。

   ThradFactory  threadFactory  :线程工厂

        线程工厂 通过这个工厂类来创建线程对象。线程工厂(Thread Factory)是用于创建线程的对象或方法。它提供了一种统一的方式来创建线程,并可以对线程进行自定义配置和初始化。线程工厂通常包含以下主要功能:

  1. 创建线程:线程工厂负责创建新的线程对象。通过线程工厂,可以使用特定的方式创建线程,例如设置线程的名称、优先级、线程组等属性。

  2. 配置线程:线程工厂允许对线程进行自定义配置和初始化。可以在创建线程时指定线程的运行环境、上下文、异常处理器等。

  3. 线程命名:线程工厂可以为创建的线程设置一个有意义的名称,以便在日志和调试中更好地追踪和识别线程。

        线程工厂的作用是封装线程的创建过程,提供了一种可扩展和可定制的方式来创建线程。通过使用线程工厂,可以对线程进行统一管理和配置,使得线程的创建和使用更加灵活和可控。

 RejectedExecutionHandler handler:(面试可能会问)

    拒绝策略  在一个线程池中,有一个阻塞队列。能够容纳的元素有上限的,当任务队列满了,如果再往里加任务时,就会用到拒绝策略。

 第一个策略: 继续添加任务时,会抛异常。新任务和旧任务都不运行了。

 第二个策略:继续添加任务时,会抛异常。新的任务,由添加新任务的线程来执行。谁添加谁来执行。

 第三个策略:继续添加任务时,会抛异常。旧的任务不执行了。执行新的任务。 

 第四个策略:继续添加任务时,会抛异常。丢弃最新的任务,新任务不会执行。

 用标准库:

ExecutorService pool = Executors.newFixedThreadPool(10);
pool.submit(new Runnable() {
 @Override
 public void run() {
 System.out.println("hello");
 }
});

3.实现一个线程池

代码:

package 多线程;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;

class MyThreadPoolExecutor{
    private List<Thread> threadList = new ArrayList<>();

    //就是一个用来保存任务的队列。
    private BlockingDeque<Runnable> queue = new LinkedBlockingDeque<>(1000);


    //通过 n 指定创建多少个线程

    public MyThreadPoolExecutor(int n){
        for (int i = 0; i < n; i++) {
            Thread t  = new Thread(()->{
               //线程要做的事情就是吧任务队列中的任务不停的取出来,并且进行执行
               while (true){
                   try {
                       //此处的 take 带有阻塞功能的
                       //如果队列为空,此处 的 take 就会阻塞
                       Runnable runnable =  queue.take();
                       //取出一个任务就执行一个任务
                       runnable.run();
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
               }
            });
            t.start();
            threadList.add(t);
        }
    }

    public void submit(Runnable runnable) throws InterruptedException{
        queue.put(runnable);
    }


}

public class ThreadDemo26 {
    public static void main(String[] args) throws InterruptedException {
        MyThreadPoolExecutor executor = new MyThreadPoolExecutor(4);
        for (int i = 0; i < 1000; i++) {
            int n = i;
            executor.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("执行任务" + n + "当前线程为:" + Thread.currentThread().getName());
                }
            });
        }
    }
}

 运行结果:我们可以看到任务不是按顺序执行的,因为当线程接到任务时,并不是立刻执行。所以任务3排到任务17后面去了。

 

                                              本期分享结束,希望大家多多支持!!! 

 

  • 18
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

所遇皆随风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值