JavaEE 08 线程池简介

2023-12-14 12:32:48

前言

前面我们谈完了定时器,单例模式,阻塞队列等的操作并且做了模拟实现,今天我们再来说一说线程池的操作以及一些锁策略.

注:本章几乎均为理论篇,实践较少.

下面就让我们开始吧.

线程池

我们知道因为进程的频繁创建和销毁,带来的开销过大,我们无法接受,所以我们引入了更轻量级的线程,但是其实这里的线程频繁消耗的话,带来的开销也是我们无法接受的,所以我们又想了两个方案,线程池方案或者是更加轻量级的协程/纤程?

纤程本质上是靠程序员在用户态进行调度,不是靠内核的调度器来操作,这节省了很多的开销

举个例子,如果一个进程中开一千个线程,电脑就卡死了,但是开一千个协程,其实是轻轻松松的

线程池的应用来说就是把线程提前创建好,用完了不要着急销毁,放进线程池里,以备下次使用,在这个过程中并没有频繁的创建和销毁线程,所以相对来说开销就小得多了,只是从线程池中取线程来使用,用完了还给线程池即可

tips:内核态和用户态之间的交互可以理解为,你去银行办事情,工作人员让你去去整一个身份证复印件,你可以让他帮你整,或者去自己整,他帮你整的话你无法掌控他什么时候帮你整,但是你自己整的话就能确定自己的时间安排

JVM提供的线程池(了解参数即可)

这里我们只要了解最后一个线程池的参数即可,因为几个方法的参数是重复的,最后一个的参数是最全的.

corePoolSize: 核心线程数? ? ? ? ? ?一个线程池里,最少有多少个线程

maximumPoolSize :最大线程数? ? 一个线程池中,最多有多少个线程

keepAliveTime:线程空闲超过这个时间阈值,就会被销毁

unit:? ? ? ? ? ? ? ? ?时间单位,取分钟,秒,小时等等

workQueue:? ? 和定时器一样,线程池也可以有很多任务,也可以设置为带有优先级的

threadFactory:? 线程工厂,本质上是给new这个操作封装了一层,可能同名同参数的构造方法,这样构成不了重载,我们就想弥补一下这个缺陷,封装一层构造方法.

handler:拒绝策略(最重要的)

以下是四个Java标准库中提供的拒绝策略

解决的是在阻塞队列满了之后,你还想往里面添加任务,我们以何种方式拒绝

第一种:直接不干了,旧任务和新任务都不干了,直接抛一个异常

第二种:新的任务,由添加任务的线程自己执行

第三种:丢弃一个最老的任务来执行这个任务

第四种:直接丢弃最新的任务

.

但是这个类使用起来还是比较复杂的,所以标准库还提供了另一个版本来简化操作,Exectors

都是通过submit添加任务,只不过是构造方法有所差异

所以如果你想实现高度定制化的线程池就使用上面这个很多参数的,不然就可以使用Exectors即可

注:一个线程池中有多少线程不是根据网上说的cpu核心数-1等等这么简单,其实还是有很多细节之处的,需要我们通过测试来决定,因为有些线程是IO密集型,有些是cpu密集型的,根据情况而定

线程池的简单实现

使用一个列表来存放队列,使用一个阻塞队列来存放任务,其中只有一个submit方法来新建任务

class MyThreadPool{

    private List<Thread> threadList = new ArrayList<>();
    private BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(1000);

    public MyThreadPool(int n){
        for (int i = 0; i < n; i++) {
            Thread t = new Thread(()->{
                //TODO
                while(true){
                    try {
                        //队列为空则会阻塞
                        Runnable runnable = queue.take();
                        //取出任务直接执行就行
                        runnable.run();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            });
            t.start();
            threadList.add(t);
        }
    }
    public void submit(Runnable runnable) throws InterruptedException {
        queue.put(runnable);
    }
}

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