栏目分类:
子分类:
返回
文库吧用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
文库吧 > IT > 软件开发 > 后端开发 > Java

java线程池及线程池运行流程

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java线程池及线程池运行流程

一、线程池的优势

1.减少资源消耗 :通过重复利用已创建的线程降低线程创建和销毁造成的消耗。

2.提高响应速度:当任务到达时,任务可以不需要等到线程创建就能立即执行。

3.方便管理:对线程进行统一的分配,监控和调优。

二、线程池运行流程

1. 可能大家已经了解了线程池的参数,但是对线程池整体的运行流程还不是很清晰,下面我将利用去银行取款的场景来模拟线程池的运行,本文的核心,希望仔细阅读,必有收获。

2. 参数对照

        所有的柜台 = 线程池

        核心线程数 = 所有普通银行柜员
        最大线程数 = 银行大厅经理
        队列 = 银行的座位
        保安 = 拒绝策略

        经理观察时间 = keepAliveTime
        时间单位 = unit
3. 运行流程介绍

step1 : 假设有一天你去银行取钱,正常情况我们就去柜台办理。
类比程序:相当于,一个任务来了,我们直接交给核心线程去处理。
step2: 假设我们看到所有柜员都在在办理业务,那我们只能在座位上等待。
类比程序:相当于,核心线程数满了,任务就被放到队列里面去了。
step3: 假设所有座位也坐满了,这时候大厅经理发现人太多了,他说我开一个vip窗口吧,我也帮忙处理一下,然后叫座位上的人来他的vip窗口办理业务。
类比程序:相当于核心线程数满了,队列也满了,那我们就把任务放到最大线程数里面。
step4: 假设所有柜台也有人,座位也满了,vip窗口也在办理,保安发现在大厅外还有人想进来办理业务,这时候保安说我得保证大厅内正常的运行,外面人不允许进来了。
类比程序:相当于核心线程数满了,队列也满了,最大线程数也满了,那么我们就执行拒绝策略。

step5: 假设办理高峰期过了,经理发现,座位已经空出来了,正常的柜员办理业务就够用了,于是他决定在vip柜台观察10分钟,如果没有人没有把座位再次坐满的话,他就有撤销vip窗口了。
类似程序:相当于队列已经不满了,最大线程数已经停止工作了,并且等待了10(keepAliveTime)分钟(unit), 都没有高峰期了,那么线程池将收回最大线程数,保留核心线程数。
 

三、线程池的参数

    
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

corePoolSize(必需):核心线程数。默认情况下,核心线程会一直存活,但是当将 allowCoreThreadTimeout 设置为 true 时,核心线程也会超时回收。
maximumPoolSize(必需):线程池所能容纳的最大线程数。当活跃线程数达到该数值后,后续的新任务将会阻塞。
keepAliveTime(必需):线程闲置超时时长。如果超过该时长,非核心线程就会被回收。如果将 allowCoreThreadTimeout 设置为 true 时,核心线程也会超时回收。
unit(必需):指定 keepAliveTime 参数的时间单位。常用的有:TimeUnit.MILLISECONDS(毫秒)、TimeUnit.SECONDS(秒)、TimeUnit.MINUTES(分)。
workQueue(必需):任务队列。通过线程池的 execute() 方法提交的 Runnable 对象将存储在该参数中。其采用阻塞队列实现。
threadFactory(可选):线程工厂。用于指定为线程池创建新线程的方式。
handler(可选):拒绝策略。当达到最大线程数时需要执行的饱和策略。


四、参数详解

1.任务队列(workQueue):

ArrayBlockingQueue:一个由数组结构组成的有界阻塞队列(数组结构可配合指针实现一个环形队列)。
LinkedBlockingQueue: 一个由链表结构组成的有界阻塞队列,在未指明容量时,容量默认为 Integer.MAX_VALUE。
PriorityBlockingQueue: 一个支持优先级排序的无界阻塞队列,对元素没有要求,可以实现 Comparable 接口也可以提供 Comparator 来对队列中的元素进行比较。跟时间没有任何关系,仅仅是按照优先级取任务。
DelayQueue:类似于PriorityBlockingQueue,是二叉堆实现的无界优先级阻塞队列。要求元素都实现 Delayed 接口,通过执行时延从队列中提取任务,时间没到任务取不出来。
SynchronousQueue: 一个不存储元素的阻塞队列,消费者线程调用 take() 方法的时候就会发生阻塞,直到有一个生产者线程生产了一个元素,消费者线程就可以拿到这个元素并返回;生产者线程调用 put() 方法的时候也会发生阻塞,直到有一个消费者线程消费了一个元素,生产者才会返回。
LinkedBlockingDeque: 使用双向队列实现的有界双端阻塞队列。双端意味着可以像普通队列一样 FIFO(先进先出),也可以像栈一样 FILO(先进后出)。
LinkedTransferQueue: 它是ConcurrentLinkedQueue、LinkedBlockingQueue 和 SynchronousQueue 的结合体,但是把它用在 ThreadPoolExecutor 中,和 LinkedBlockingQueue 行为一致,但是是无界的阻塞队列。

2.拒绝策略(handler)

AbortPolicy(默认):丢弃任务并抛出 RejectedExecutionException 异常。

CallerRunsPolicy:由调用线程处理该任务。   

DiscardPolicy:丢弃任务,但是不抛出异常。可以配合这种模式进行自定义的处理方式。

DiscardOldestPolicy:丢弃队列最早的未处理任务,然后重新尝试执行任务。

3.线程工厂(threadFactory)

默认已帮我们实现,但是工作中一般我们用于自定义定义线程池的名字,由于项目中存在很多线程池,定义特殊含义的名字可以帮助我们在生产中快速的查找日志,识别哪个线程池出了异常。

  private static ThreadPoolExecutor executor = new ThreadPoolExecutor(20, 100, 1,
      TimeUnit.MINUTES, new LinkedBlockingQueue<>(1000),
      new CustomizableThreadFactory("thread-demo-"),
      new ThreadPoolExecutor.CallerRunsPolicy()
  );

 

转载请注明:文章转载自 www.wk8.com.cn
本文地址:https://www.wk8.com.cn/it/1039670.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 wk8.com.cn

ICP备案号:晋ICP备2021003244-6号