线程池使用

基本概念

程序

是为了完成特定任务、用某种语言编写的一组指令的集合

进程

  • 进程是指定运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存空间。
  • 进程是程序的一次执行过程,或是正在运行的一个程序。是动态程序: 有它自身的产生、存在、和消亡的过程。

线程

  • 操作系统中可独立执行的最小单位。
  • 线程由进程创建的,是进程的一个实体
  • 一个进程可以拥有多个线程,它们共享进程的资源。
    • 线程: 同一个时刻,只允许执行一个线程
    • 多线程: 同一个时刻,可以执行多个线程
    • 并发: 同一个时刻,多个任务交替执行,造成一种"貌似同时"的错觉,简单的说,单核cpu实现的多任务就是并发。
    • 并行: 同一个时刻,多个任务同时执行。多核cpu可以实现并行

线程基本使用、线程同步、锁机制详细相关:https://blog.csdn.net/qq_47200222/article/details/123055965

拓展

线程的一些核心概念 :

  1. 并发执行:线程使得程序能够并发执行,即多个线程可以同时执行不同的任务或代码片段,从而提高程序的执行效率和响应性。
  2. 线程调度:线程调度是操作系统决定何时运行哪个线程的过程。操作系统使用调度算法来决定线程的执行顺序和时间片分配,以实现公平性和性能优化。
  3. 线程状态:线程可以处于不同的状态,包括就绪(Ready)、运行(Running)、阻塞(Blocked)和终止(Terminated)等。线程的状态可以随着程序的执行和操作系统的调度而变化。
  4. 线程间通信:线程可以通过共享内存或消息传递等方式进行通信和同步操作。线程间通信是多线程编程中常用的技术,用于实现数据共享、任务协作和数据同步等功能。
  5. 线程安全性:线程安全性是指在多线程环境下保证数据和资源的正确访问的性质。线程安全的代码可以在多线程环境中正确地执行,而不会出现竞态条件、死锁和数据损坏等问题。
  6. 线程优先级:线程可以设置优先级,用于指示线程执行的相对重要性。优先级高的线程在竞争资源时会更有可能被调度执行,但并不保证高优先级线程一定比低优先级线程先执行。

线程池

1.终极指南

【Thread】线程池的 7 种创建方式及自定义线程池

https://blog.csdn.net/sco5282/article/details/120963463

2.介绍

线程池(ThreadPool)是一种基于池化思想管理和使用线程的机制:它是将多个线程预先存储在一个"池子"内,当有任务出现时可以避免重新创建和销毁线程所带来性能开销,只需要从"池子"内取出相应的线程执行对应的任务即可。

使用线程池主要有以下优点:

  • 降低资源消耗(复用线程,减少线程频繁新建、销毁等带来的开销)
  • 提高响应速度
  • 提高线程的可管理性

3.特别注意

线程池本身是异步的,内部线程同步执行操作。

【强制】阿里巴巴在其《Java开发手册》中也强制规定:线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。
【强制】线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。

Executors 返回的线程池对象的弊端如下:

1)FixedThreadPool 和 SingleThreadPool:允许的请求队列长度Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM。

2)CachedThreadPool:允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM。

4.ThreadPoolExecutor执行流程

ThreadPoolExecutor 关键节点的执行流程如下:

  • 当线程数小于核心线程数时,创建线程。
  • 当线程数大于等于核心线程数,且任务队列未满时,将任务放入任务队列。
  • 当线程数大于等于核心线程数,且任务队列已满:若线程数小于最大线程数,创建线程;若线程数等于最大线程数,抛出异常,拒绝任务。

5.使用

java 复制代码
@Configuration("myThreadPool")
class ThreadPoolConfig {
    //可作为配置类进行使用
    private int corePoolSize = 5 
    private int maximumPoolSize = 10
    private long keepAliveTime = 60L 

    @Bean
     ThreadPoolExecutor creatThreadPool(){
        return new ThreadPoolExecutor(corePoolSize,
                               maximumPoolSize,
                               keepAliveTime,
                               TimeUnit.SECONDS, //存活时间单位
                               new LinkedBlockingQueue<>(10),//无界任务队列,线程池的任务队列可以无限制的添加新的任务
                               CustomerThreadFactory("my-thread-pool")      ,
                               ThreadPoolExecutor.CallerRunsPolicy());//拒绝机制

    }

    //自定义命名线程池的线程
    static class CustomerThreadFactory(String name) implements ThreadFactory {
        private final AtomicInteger mThreadNum = new AtomicInteger(1);
        
        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r, name + + mThreadNum.getAndIncrement());
        }
    }

}


//Service业务层使用
@Autowired
private lateinit ThreadPoolExecutor myThreadPool

fun main(){
    ...
    asynchronousProcessData()
    return
}

fun asynchronousProcessData(){
    Runnable r = new Runnable() {
        //内部处理逻辑为子线程
        ...
    }

    myThreadPool.execute(r) //主线程
}

spring boot使用自定义配置的线程池执行Async异步任务 - 晨曦曙光 - 博客园

协程(kotlin、go)

协程的原理_协程原理-CSDN博客

线程是在操作系统 进行,协程(Coroutine)是在用户空间进行的。

线程是操作系统的最小执行单元,因此协程是基于线程的,协程的创建、切换、销毁都是在某个线程中来进行的。

关键特点:

  1. 轻量级:协程由程序员控制,不需要像线程那样创建和维护额外的操作系统资源,因此占用的资源更少,启动和切换的开销更小。
  2. 协作式调度:协程采用协作式调度方式,即由协程自身主动让出执行权给其他协程。协程之间通过显式的挂起(suspend)和恢复(resume)操作进行通信和切换。
  3. 非抢占式:协程不会被强制中断或抢占执行,只有在协程主动挂起时才会切换到其他协程。这种特性可以有效避免竞态条件和死锁等并发编程问题。
  4. 状态保存和恢复:协程可以在执行过程中保存自己的状态,并在恢复执行时继续从之前的状态处开始。这使得协程可以实现复杂的控制流和异步编程模式。

使用场景:

  1. 协程切换成本比线程的切换成本比较低。
  • 一是系统线程会占用非常多的内存空间,二是过多的线程切换会占用大量的系统时间。
  • 协程并没有增加线程的数量,只是在线程的基础上通过分时复用的方式运行多个协程,而且协程的切换在用户态完成,切换的代价比线程从用户态到内核态的代价小很多。

在协程中不能调用导致线程阻塞的操作。也就是说,协程只有和异步IO结合起来,才能发挥最大的威力。

在协程中调用阻塞IO的操作处理方式:

  • 在调用阻塞IO操作的时候,重新启动一个线程去执行这个操作,等执行完成后,协程再去读取结果。这其实和多线程没有太大区别。
  • 对系统的IO进行封装,改成异步调用的方式,这需要大量的工作,最好寄希望于编程语言原生支持。
相关推荐
不爱吃糖的程序媛2 小时前
鸿蒙PC端Java应用开发实战:从环境适配到系统信息采集
java·华为·harmonyos
鹿角片ljp2 小时前
深入理解Java集合框架:核心接口与实现解析
java·开发语言·windows
小贝IT~2 小时前
基于SpringBoot的网页时装购物系统-049
java·spring boot·后端
独自破碎E2 小时前
什么是循环依赖
java·mysql·mybatis
heartbeat..2 小时前
Java NIO 详解(Channel+Buffer+Selector)
java·开发语言·文件·nio
2401_837088502 小时前
Hot 146 LRU Cache 实现详解
java·开发语言
悟空码字2 小时前
文档变形记,SpringBoot实战:3步让Word乖乖变PDF
java·spring boot·后端
用户2190326527352 小时前
能省事”。SpringBoot+MyBatis-Plus:开发效率提升10倍!
java·spring boot·mybatis