zoukankan      html  css  js  c++  java
  • 如何优化 ThreadPoolExecutor

    一、想让线程池在初始化时就干活,而不是等到第一次提交任务时才创建线程,该怎么做?

        /**
         * Starts all core threads, causing them to idly wait for work. This
         * overrides the default policy of starting core threads only when
         * new tasks are executed.
         *
         * @return the number of threads started
         */
        public int prestartAllCoreThreads() {
            int n = 0;
            while (addWorker(null, true))
                ++n;
            return n;
        } 

    二、tomcat 8 如何优化ThreadPoolExecutor

      1.  tomcat优化:ThreadPoolExecutor#execute 在抛出 RejectedExecutionException时, 仍然尝试给队列添加任务

        /**
         * Executes the given command at some time in the future.  The command
         * may execute in a new thread, in a pooled thread, or in the calling
         * thread, at the discretion of the <tt>Executor</tt> implementation.
         * If no threads are available, it will be added to the work queue.
         * If the work queue is full, the system will wait for the specified
         * time and it throw a RejectedExecutionException if the queue is still
         * full after that.
         *
         * @param command the runnable task
         * @throws RejectedExecutionException if this task cannot be
         * accepted for execution - the queue is full
         * @throws NullPointerException if command or unit is null
         */
        public void execute(Runnable command, long timeout, TimeUnit unit) {
            submittedCount.incrementAndGet();
            try {
                super.execute(command);
            } catch (RejectedExecutionException rx) {
                if (super.getQueue() instanceof TaskQueue) {
                    final TaskQueue queue = (TaskQueue)super.getQueue();
                    try {
                        if (!queue.force(command, timeout, unit)) {
                            submittedCount.decrementAndGet();
                            throw new RejectedExecutionException("Queue capacity is full.");
                        }
                    } catch (InterruptedException x) {
                        submittedCount.decrementAndGet();
                        throw new RejectedExecutionException(x);
                    }
                } else {
                    submittedCount.decrementAndGet();
                    throw rx;
                }
    
            }
        }

      2. TaskQueue 继承 LinkedBlockingQueue, 重写了offer方法

    也可以分析下tomcat线程池在防止内存溢出方面做的工作

    tomcat的ThreadExecutor其中一个重要的作用,就是对线程的ThreadLocal缓存的变量进行清理;(待验证)

    为什么ThreadLocal要进行清理呢?如果是一个简单的main函数的话,那么在这个主线程中使用ThreadLocal缓存在程序结束之后,自动就随着JVM退出而消亡了;

    如果是开启的一个线程,这个线程中使用了ThreadLocal缓存,线程退出,这种情况这块内存仍旧会进行回收;但是,线程池的线程是重复利用的,

    很有可能会在某处使用了ThreadLocal缓存,但是忘记remove掉了,这种在线程池中是很致命的

  • 相关阅读:
    期货结算 期货算法公式
    c# websocket 服务端,客户端 兼容低版本IE,支持超长数据传输 附源码
    翻译API translate api 翻译文档api 百度翻译
    asp.net c# 网页 导出excel 多表格 多个sheet
    创建单线程单元 asp.net下使用WebBrowser
    c++ 修改内存
    c++ int to byte
    webservice 第一节 .net SoapHeader验证
    myeclipse maven编译出错
    java用正则表达式获取domain
  • 原文地址:https://www.cnblogs.com/yuyutianxia/p/9286838.html
Copyright © 2011-2022 走看看