线程池实现

发布时间:2023年12月24日

? 作者:小胡_不糊涂
🌱 作者主页:小胡_不糊涂的个人主页
📀 收录专栏:JavaEE
💖 持续更文,关注博主少走弯路,谢谢大家支持 💖

1. 什么是线程池

想象这么?个场景:
在学校附近新开了?家快递店,?板很精明,想到?个与众不同的办法来经营。店?没有雇?,?是每次有业务来了,就现场找?名同学过来把快递送了,然后解雇同学。这个类?我们平时来?个任务,启动?个线程进?处理的模式。

很快?板发现问题来了,每次招聘 + 解雇同学的成本还是?常?的。?板还是很善于变通的,知道了为什么?家都要雇?了,所以指定了?个指标,公司业务?员会扩张到3个?,但还是随着业务逐步雇?。于是再有业务来了,?板就看,如果现在公司还没3个?,就雇?个?去送快递,否则只是把业务记下来,等着3个快递?员空闲的时候去处理。这个就是我们要带出的线程池的模式

线程池最?的好处就是减少每次启动、销毁线程的损耗。

2. 标准库中的线程池

在Java中可以使?Executors.newFixedThreadPool(10) 能创建出固定包含10个线程的线程池。返回值类型为 ExecutorService,然后通过 ExecutorService.submit 可以注册?个任务到线程池中。

public static void main(String[] args) {
        ExecutorService  service=Executors.newFixedThreadPool(10);
        service.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello");
            }
        });
    }

Executors 创建线程池的几种?式:

  • newFixedThreadPool:创建固定线程数的线程池
  • newCachedThreadPool:创建线程数?动态增?的线程池
  • newSingleThreadExecutor:创建只包含单个线程的线程池
  • newScheduledThreadPool:设定延迟时间后执?命令,或者定期执?命令。是进阶版的 Timer
    Executors 本质上是 ThreadPoolExecutor 类的封装

ThreadPoolExecutor 提供了更多的可选参数,可以进?步细化线程池?为的设定:
在这里插入图片描述

  • corePoolSize:正式员?的数量。(正式员?,?旦录?,永不辞退)
  • maximumPoolSize:正式员? + 临时?的数?。(临时?:?段时间不?活,就被辞退)
  • keepAliveTime:临时?允许的空闲时间
  • unit:keepaliveTime 的时间单位
  • workQueue:传递任务的阻塞队列
  • threadFactory:创建线程的??,参与具体的创建线程?作。通过不同线程??创建出的线程相当于对?些属性进?了不同的初始化设置
  • RejectedExecutionHandler:拒绝策略,如果任务量超出公司的负荷了接下来怎么处理

3. 线程池模拟实现

主要思路:
1.提供构造方法,指定创建多少个线程
2.在构造方法中,把这些线程都创建好
3.有一个阻塞队列,能够持有要执行的任务
4.提供submit方法,可以添加新的任务

class MyThreadPoolExecutor{
    private List<Thread> threadList=new ArrayList<>();//保存产生的线程
    private BlockingQueue<Runnable> queue=new ArrayBlockingQueue<>(1000);//保存任务的队列

    //通过n指定创建多少个线程
    public  MyThreadPoolExecutor(int n) {
        for (int i = 0; i < n; i++) {
            //取出任务并执行
            Thread t = new Thread(() -> {
                while(true){
                    try {
                        Runnable runnable=queue.take();///如果队列为空,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 TestDemo9 {
    //public static volatile int i=0;
    public static void main(String[] args) throws InterruptedException {
        MyThreadPoolExecutor executor = new MyThreadPoolExecutor(4);
        for (int i = 0; i < 10; i++) {
            int n = i;//防止变量捕获(不可以是一直变化的值)-->volatile
            executor.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("执行任务" + n + "当前任务的线程为:" + Thread.currentThread().getName());
                }
            });

        }
    }
} 

在这里插入图片描述

多个线程之间的执行顺序是不确定的,某个线程取到任务也并非是立即就执行,就会产生无序的结果。但此处这些线程都是等价的。

文章来源:https://blog.csdn.net/iLoyo_/article/details/135181511
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。