• 线程池


    更细节的:https://blog.csdn.net/weixin_40271838/article/details/79998327

    1.  为什么要使用线程池?

       假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中执行任务的时间,T3 销毁线程时间。 如果:T1 + T3 远大于 T2,这个时候就可以使用线程池了。官方一点的讲法:创建线程和销毁线程的花销是比较大的,这些时间有可能比处理业务的时间还要长。这样频繁的创建线程和销毁线程,再加上业务工作线程,消耗系统资源的时间,可能导致系统资源不足,这个时候就需要使用线程池了。

    2.  线程池的作用:

       1.提高效率 创建好一定数量的线程放在池中,等需要使用的时候就从池中拿一个,这要比需要的时候创建一个线程对象要快的多。

       2.方便管理 可以编写线程池管理代码对池中的线程同一进行管理。

    3.  常见的线程池

       1.newSingleThreadExecutor

       单个线程的线程池,即线程池中每次只有一个线程工作,单线程串行执行任务。
       2.newFixedThreadPool
       创建一个固定数量的线程池,可控制线程最大并发数,提交一个任务就是一个线程,直到达到线程池的最大数量,然后后面进入等待队列直到前面的任务完成才继续执行。
       3.newCacheThreadExecutor(推荐使用)
       可缓存线程池,当线程池大小超过了处理任务所需的线程,那么就会回收部分空闲(一般是60秒无执行)的线程,当有任务来时,又智能的添加新线程来执行。
       4.newScheduleThreadExecutor
       大小无限制的线程池,支持定时和周期性的执行线程
    4.  线程池中的几种重要的参数
       1.corePoolSize:核心池的大小,在创建了线程池后,默认情况下,线程池中并没有任何线程,而是等待有任务到来才创建线程去执行任务,除非调用了prestartAllCoreThreads()或prestartCoreThread()方法默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中。
       2.maximumPoolSize:线程池最大线程数,它表示在线程池中最多能创建多少个线程;
       3.keepAliveTime:表示线程没有任务执行时最多保持多久时间会终止。默认情况下,只有当线程池中的线程数大于corePoolSize时,keepAliveTime才会起作用。
       4.unit:参数keepAliveTime的时间单位,有7种取值(天,小时,分钟,秒,毫秒,微秒,纳秒)。
       5.workQueue:一个阻塞队列,用来存储等待执行的任务,一般有一下三种选择:ArrayBlockingQueue;LinkedBlockingQueue;SynchronousQueue;
       6.threadFactory:线程工厂,主要用来创建线程
    5.  线程池的几种状态:定义了一个volatile变量,另外定义了几个static final变量表示线程池的各个状态:
    volatile int runState;
    static final int RUNNING    = 0;
    static final int SHUTDOWN   = 1;
    static final int STOP       = 2;
    static final int TERMINATED = 3;

       runState表示当前线程池的状态,它是一个volatile变量用来保证线程之间的可见性;至于为什么用volatile 可以看https://www.cnblogs.com/jkzr/p/10576268.html

       RUNNING 状态:线程池正在运行;SHUTDOWN状态:此时线程池不能够接受新的任务,它会等待所有任务执行完毕;

       STOP状态:此时线程池不能接受新的任务,并且会去尝试终止正在执行的任务;TERMINATED状态:所有工作线程已经销毁,任务缓存队列已经清空或执行结束后。

    6.  任务提交给线程池之后的处理策略,这里总结一下主要有4点:

       1.如果当前线程池中的线程数目小于corePoolSize,则每来一个任务,就会创建一个线程去执行这个任务;

       2.如果当前线程池中的线程数目>=corePoolSize,则每来一个任务,会尝试将其添加到任务缓存队列当中,若添加成功,则该任务会等待空闲线程将其取出去执行;若添加失败(一般来说是任务缓存队列已满),则会尝试创建新的线程去执行这个任务;

       3.如果当前线程池中的线程数目达到maximumPoolSize,则会采取任务拒绝策略进行处理;

       4.如果线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止,直至线程池中的线程数目不大于corePoolSize;如果允许为核心池中的线程设置存活时间,那么核心池中的线程空闲时间超过keepAliveTime,线程也会被终止。

  • 相关阅读:
    在python3中安装mysql扩展,No module named 'ConfigParser'
    Ubuntu安装MySQL和Python库MySQLdb步骤
    python_非阻塞套接字及I/O流
    EFI、UEFI、MBR、GPT的区别
    2018.1.9 博客迁移至csdn
    2017.12.27 sqlSessionFactory和sqlSession(to be continued)
    2017.12.25 Mybatis物理分页插件PageHelper的使用(二)
    2017.12.14 Mybatis物理分页插件PageHelper的使用(一)
    2017.12.12 架构探险-第一章-从一个简单的web应用开始
    2017.12.11 线程池的简单实践
  • 原文地址:https://www.cnblogs.com/jkzr/p/10619195.html
Copyright © 2020-2023  润新知