线程P6 | 线程池的理解+模拟实现线程池

什么是线程池

老规矩,在正式介绍这个东西之前,我们还是先给大家先简单介绍一下啥是线程池

线程池是一种多线程处理技术,它通过预先创建一组可复用的线程,来高效地管理和执行多个任务,避免频繁创建和销毁线程带来的性能开销。

嘶...看起来感觉好复杂呢.....其实直白说来,就是你把线程池想象成鱼塘,里面的一个一个线程就是一条条你养的🐟,在线程里面有个阻塞队列,里面装满了任务,就好比是一条条蚯蚓,你开始往里面丢蚯蚓,🐟就会一条条来抢,一条抢到了这个蚯蚓,其它鱼就只能等着下一条蚯蚓来了~~而正在吃蚯蚓的鱼呢,也不会去参与争抢

线程池里面有一些创建好的线程,你只需要往里面丢任务,线程们就会抢着来执行~~线程池大概就是这么个意思

ThreadPoolExecutor线程池的参数

接下来,我们就来了解一下ThreadPoolExecutor这个类,它有下面7个参数

|---------------------|----------------------|
| 参数 | 说明 |
| corePoolSize | 核心线程数,线程池中维持的最小线程数 |
| maximumPoolSize | 最大线程数 |
| keepAliveTime | 除核心线程外其余线程可以存活的最长时间 |
| unit | keepAliveTime的时间单位 |
| workQueue | 工作队列 |
| threadFactory | 用于创建新线程的工厂 |
| handler | 当队列和线程池饱和的时候会采用的拒绝策略 |

这里我们再拓展讲一下拒绝策略

拒绝策略

这里我们还是用一个生活化的例子来理解一下这四个拒绝策略

假设你现在课程表已经一堆课了,然后老师说还要让你帮忙做一个项目...

|---------------------|------------------------------------------------|
| 策略 | 说明 |
| AbortPolicy | 就是你感觉压力太大了,直接崩溃了,不仅无法完成这个项目,连课都没心思上了,线程池就直接崩溃了 |
| CallerRunsPolicy | 你委婉地让老师自己做这个项目 |
| DiscardOldestPolicy | 你准备逃一些差不多要修完的课来做项目 |
| DiscardPolicy | 你直接拒绝了老师的请求 |

Executors工厂类

ThreadPoolExecutor类创建线程池的话还是比较麻烦的,需要规定很多参数,所以我们在创建线程池的时候可以用Executors这个工厂类来进行创建,它也提供了几个创建线程池的方法

|----------------------|--------------------------|
| 方法 | 说明 |
| FixedThreadPool | 固定线程数的线程池 |
| CachedThreadPool | 线程数可变的线程池 |
| SingleThreadExecutor | 单线程线程池,池子里面只有一个线程来执行所有任务 |
| ScheduledThreadPool | 定时任务线程池,相当于是带Timer的线程池 |

使用例子

java 复制代码
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Demo26 {
    public static void main(String[] args) {
        //创建一个固定5个线程的线程池
        ExecutorService threadPool = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 1000; i++) {
            int id = i;
            threadPool.submit(() -> {
                System.out.println(Thread.currentThread().getName() + "正在打印" + id);
            });
        }
    }
}

模拟实现一个固定线程的线程池

java 复制代码
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

class MyThreadPool {
    private BlockingQueue<Runnable> queue = null;

    public MyThreadPool(int n) throws InterruptedException {
        queue = new ArrayBlockingQueue<>(1000);

        //创建n个线程
        for (int i = 0; i < n; i++) {
            Thread t = new Thread(() -> {
                try {
                    while (true) {
                        Runnable task = queue.take();
                        task.run();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, "线程"+(i+""));

            t.start();
        }
    }

    public void submit(Runnable task) throws InterruptedException {
        queue.put(task);
    }
}
public class Demo25 {
    public static void main(String[] args) throws InterruptedException {
        MyThreadPool threadPool = new MyThreadPool(5);
        for (int i = 0; i < 1000; i++) {
            int id = i;
            threadPool.submit(() -> {
                System.out.println(Thread.currentThread().getName() + "正在打印" + id);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
    }
}

❤❤感谢观看~~对你有帮助的话给博主点个大大的赞吧(●'◡'●)谢谢~~~❤❤