【线程池】java线程池执行流程理解

「爱情、让人受尽委屈。」 2022-08-22 14:27 431阅读 0赞

有时候项目中要使用到队列和多线程,写个例子留着随笔,方便后续使用

大家都知道,多线程是为了能更高效的运行程序,而线程池是为了控制一个进程中线程过多而导致内存溢出的问题,队列主要是为了解决了某一时刻请求过多而出现的宕机情况,同时能接收处理更多的请求,可以将多个请求放置到队列中,等待线程依次执行,而客户端则可以继续处理其它事情。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3JvZnRo_size_16_color_FFFFFF_t_70

  1. 线程池和队列执行顺序:
  2. [1]线程池刚创建时,里面没有一个线程。任务队列是作为参数传进来的,不过就算队列里面有任务,线程池也不会马上执行它们。
  3. [2]当调用execute() 方法添加一个任务时,线程池会做如下判断:
  4. a:如果正在运行的线程数量小于corePoolSize,那么马上创建线程运行这个任务
  5. b:如果正在运行的线程数量大于或等于corePoolSize,那么将这个任务放入队列
  6. c:如果这时候队列满了,而且正在运行的线程数量小于maximumPoolSize,那么还是要创建新的线程运行这个任务
  7. d:如果队列满了,而且正在运行的线程数量大于或等于maximumPoolSize,那么线程池会抛出异常,告诉调用者“我不能再接收任务”了
  8. [3]当一个线程完成时,它会从队列中取下一个任务来执行。
  9. [4]当一个线程无事可做,超过一定的时间时,线程池会判断,如果当前运行的线程数大于corePoolSize,那么这个线程被停掉,所以线程池的所有任务完成后,它会收缩到corePoolSzie 的大小。
  10. 这个过程说明,并不是先加入任务就一定会执行。
  11. 假设队列大小为4corePoolSize2maximumPoolSize 5那么当加入15个任务时,执行的顺序类似这样:
  12. 首先执行任务12,然后任务3~6被放入队列,这个时候队列满了,任务78910会被马上执行,
  13. 而任务11~15则会抛出异常。最终的顺序是:12789103456
  14. 当然这个过程是针对指定大小的ArrayBlockingQueue<Runnable> 来说,如果是LinkedBlockingQueue<Runnable>,因为该队列无带下限制,所以不存在上述问题。

1、线程池和队列的应用小例子

(1) 线程实现类

  1. public class ThreadTest implements Runnable {
  2. @Override
  3. public void run() {
  4. /** 设置获取当前线程的名称 **/
  5. System.out.println(Thread.currentThread().getName());
  6. try{
  7. /** 设置当前线程休眠3秒钟 **/
  8. Thread.sleep(3000);
  9. } catch(InterruptedException e) {
  10. e.printStackTrace();
  11. }
  12. }
  13. }
  14. (2) 主线程类
  15. public static void main(String[] args ) throws InterruptedException {
  16. /** 创建一个线程队列,不指定队列大小,则无大小限制,队列存放线程超类 **/
  17. BlockinQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();
  18. /** 创建线程池对象,线程池根据参数创建指定个数的线程, 这里2指:空闲线程个数,6是指:最大线程个数,1是指:一个线程不工作时,超过该时间就**/ /** 就停止该线程,TimeUnit.DAYS是指:时间的单位,queue是指:存放需要被线程池执行的线程队列 **/
  19. ThreadPoolExecuter executor = new ThreadPoolExecutor(2,6,1,TimeUnit.DAYS,queue);
  20. for(int i=0;i<10;i++) {
  21. /** 设定每一个线程的名称 **/
  22. executor.execute(new Thread(new ThreadTest(),"ThreadName-"+i));
  23. System.out.println("线程队列大小为---->"+queue.size());
  24. }
  25. executor.shutdown();
  26. }
  27. (3) 输出结果

Center

发表评论

表情:
评论列表 (有 0 条评论,431人围观)

还没有评论,来说两句吧...

相关阅读

    相关 线执行线案例

    使用线程池执行多线程需要如下几个条件 首先是一个线程池,线程池包含一些初始化数据,包含队列大小,核心线程数,最大线程数。 然后是一个实现了 runnable的任务,将该任务

    相关 线理解

    线程池理解: 线程池就像是一个大饭店,饭店里有N多个服务员,每个服务员就相当于线程池中的每个线程,而这个店里面会来很多顾客吃饭, 每个顾客都会从门口有序排队进入