美文网首页
高并发:线程池执行流程,拒绝策略,JDK内置线程池

高并发:线程池执行流程,拒绝策略,JDK内置线程池

作者: 栢鸽 | 来源:发表于2019-05-11 14:58 被阅读0次

线程是珍贵的资源,每创建一个线程jvm都要给予分配栈空间和堆空间,创建的过程是一个比较消耗性能的过程。而且过多的线程可能会引起栈溢出或内存溢出等异常,甚至是文件句柄不够(linux默认非root用户文件句柄为1024)。

基于以上考虑,对线程进行有效的管控是一个提高性能必要的选择,特别是高并发环境下。jdk为我们提供了线程池来管理线程。

1. 线程池原理

image.png

2. 饱和策略

  1. AbortPolicy:默认的策略,直接抛出RejectedExecutionException异常
  2. CallerRunsPolicy:这个策略比较有意思,看源码可以直接内部直接调用了run方法,这相当于直接让调用execute方法的线程直接执行这个方法了。
    public static class CallerRunsPolicy implements RejectedExecutionHandler {
        /**
         * Creates a {@code CallerRunsPolicy}.
         */
        public CallerRunsPolicy() { }

        /**
         * Executes task r in the caller's thread, unless the executor
         * has been shut down, in which case the task is discarded.
         *
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                r.run();
            }
        }
    }
  1. DiscardOldestPolicy:将等待队列中的第一个任务抛弃,并重试execute方法,这个方式在高并发环境,并且大部分任务的执行时间都比较长的情况下,可能会造成现场饥饿死锁
   public static class DiscardOldestPolicy implements RejectedExecutionHandler {
        /**
         * Creates a {@code DiscardOldestPolicy} for the given executor.
         */
        public DiscardOldestPolicy() { }

        /**
         * Obtains and ignores the next task that the executor
         * would otherwise execute, if one is immediately available,
         * and then retries execution of task r, unless the executor
         * is shut down, in which case task r is instead discarded.
         *
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                e.getQueue().poll();
                e.execute(r);
            }
        }
    }
  1. DiscardPolicy:就是什么都不干,抛弃当前任务
    public static class DiscardPolicy implements RejectedExecutionHandler {
        /**
         * Creates a {@code DiscardPolicy}.
         */
        public DiscardPolicy() { }

        /**
         * Does nothing, which has the effect of discarding task r.
         *
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        }
    }

3.jdk内置的几种线程池

  1. CachedThreadPool:
    没有线程上线的线程池,线程空闲60s就回收,使用该线程要比较小心,假设创建的线程过多会使系统崩溃,不建议在高并发情况下使用。
    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
  1. FixedThreadPool:
    固定大小的线程池,使用该线程池的时候,一定要注意分配的线程数数量,避免资源的浪费或者资源的不足情况。
    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
  1. SingleThreadExecutor:
    只有单个线程,该线程池能保证任务按FIFO的顺序执行。
    public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }
  1. newScheduledThreadPool:
    创建一个定时任务线程池
    public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue());
    }

ps:在jdk1.8下的源码

相关文章

  • 高并发:线程池执行流程,拒绝策略,JDK内置线程池

    线程是珍贵的资源,每创建一个线程jvm都要给予分配栈空间和堆空间,创建的过程是一个比较消耗性能的过程。而且过多的线...

  • 线程池

    线程池执行过程 线程池生命周期 线程池分类 阻塞队列 拒绝策略 - ThreadPoolExecutor.Abor...

  • 多线程juc线程池

    java_basic juc线程池 创建线程池 handler是线程池拒绝策略 排队策略 线程池状态 RUNNIN...

  • Java线程池拒绝策略

    【Java线程池拒绝任务策略】创建线程池可以指定拒绝策略如下: 一 拒绝时机1) 调用线程池的shutdown函数...

  • 线程池 | 执行流程、拒绝策略

    线程池执行流程 想要真正的了解线程池的执行流程,就要先从线程池的执行方法execute()说起,execute()...

  • java线程池执行原理

    描述 JDK提供的工具类生成的线程池会造成内存溢出,所以需要自己定义线程池。 测试代码 线程池执行流程 提交任务流...

  • ThreadPoolExecutor

    线程池 拒绝策略 线程池的拒绝策略,即任务被添加到线程池中被拒绝而采取的处理措施。任务被拒绝的原因可能有: 线程池...

  • ThreadPoolExecutor的RejectedExecu

    java 线程池ThreadPoolExecutor的拒绝策略有: CallerRunsPolicy : 当线程池...

  • 线程池概述

    为什么要使用线程池? 线程池核心参数 线程池的几种拒绝策略 execute()和submit()的区别 线程池工作...

  • 阅读源码之线程池

    线程池流程图 更美观一点的如下图 核心类的构造函数如下 执行的核心代码 拒绝策略的执行时机一:当线程池不是运行中状...

网友评论

      本文标题:高并发:线程池执行流程,拒绝策略,JDK内置线程池

      本文链接:https://www.haomeiwen.com/subject/sqmxaqtx.html