Java Reference
In-Depth Information
One technique that can mitigate the ill effects of long-running tasks is for tasks to use
timed resource waits instead of unbounded waits. Most blocking methods in the plaform
libraries come in both untimed and timed versions, such as Thread.join , Blockin-
gQueue.put , CountDownLatch.await , and Selector.select . If the wait times
out, you can mark the task as failed and abort it or requeue it for execution later. This guaran-
tees that each task eventually makes progress towards either successful or failed completion,
freeing up threads for tasks that might complete more quickly. If a thread pool is frequently
full of blocked tasks, this may also be a sign that the pool is too small.
8.2. Sizing Thread Pools
The ideal size for a thread pool depends on the types of tasks that will be submitted and the
characteristics of the deployment system. Thread pool sizes should rarely be hard-coded; in-
stead pool sizes should be provided by a configuration mechanism or computed dynamically
by consulting Runtime.availableProcessors .
Sizing thread pools is not an exact science, but fortunately you need only avoid the extremes
of “too big” and “too small”. If a thread pool is too big, then threads compete for scarce CPU
and memory resources, resulting in higher memory usage and possible resource exhaustion.
If it is too small, throughput suffers as processors go unused despite available work.
To size a thread pool properly, you need to understand your computing environment, your
resource budget, and the nature of your tasks. How many processors does the deployment
system have? How much memory? Do tasks perform mostly computation, I/O, or some com-
bination? Do they require a scarce resource, such as a JDBC connection? If you have differ-
ent categories of tasks with very different behaviors, consider using multiple thread pools so
each can be tuned according to its workload.
For compute-intensive tasks, an N cpu -processor system usually achieves optimum utilization
with a thread pool of N cpu +1 threads. (Even compute-intensive threads occasionally take a
page fault or pause for some other reason, so an “extra” runnable thread prevents CPU cycles
from going unused when this happens.) For tasks that also include I/O or other blocking op-
erations, you want a larger pool, since not all of the threads will be schedulable at all times.
In order to size the pool properly, you must estimate the ratio of waiting time to compute
time for your tasks; this estimate need not be precise and can be obtained through pro-filing
or instrumentation. Alternatively, the size of the thread pool can be tuned by running the ap-
plication using several different pool sizes under a benchmark load and observing the level
of CPU utilization.
Search WWH ::




Custom Search