如何优化 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掉了,这种在线程池中是很致命的