如何優化 ThreadPoolExecutor

1、想讓線程池在初始化時就幹活,而不是等到第一次提交任務時才建立線程,該怎麼作?緩存

    /**
     * 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;
    } 

 

 

2、tomcat 8 如何優化ThreadPoolExecutortomcat

  1.  tomcat優化:ThreadPoolExecutor#execute 在拋出 RejectedExecutionException時, 仍然嘗試給隊列添加任務ide

    /**
     * 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緩存的變量進行清理;(待驗證)this

爲何ThreadLocal要進行清理呢?若是是一個簡單的main函數的話,那麼在這個主線程中使用ThreadLocal緩存在程序結束以後,自動就隨着JVM退出而消亡了;spa

若是是開啓的一個線程,這個線程中使用了ThreadLocal緩存,線程退出,這種狀況這塊內存仍舊會進行回收;可是,線程池的線程是重複利用的,線程

頗有可能會在某處使用了ThreadLocal緩存,可是忘記remove掉了,這種在線程池中是很致命的rest

相關文章
相關標籤/搜索