Java Reference
In-Depth Information
Tasks that use ThreadLocal . ThreadLocal allows each thread to have its own
private “version” of a variable. However, executors are free to reuse threads as they
see fit. The standard Executor implementations may reap idle threads when de-
mand is low and add new ones when demand is high, and also replace a worker thread
with a fresh one if an unchecked exception is thrown from a task. ThreadLocal
makes sense to use in pool threads only if the thread-local value has a lifetime that
is bounded by that of a task; Thread-Local should not be used in pool threads to
communicate values between tasks.
Thread pools work best when tasks are homogeneous and independent . Mixing long-running
and short-running tasks risks “clogging” the pool unless it is very large; submitting tasks that
depend on other tasks risks deadlock unless the pool is unbounded. Fortunately, requests in
typical network-based server applications—web servers, mail servers, file servers—usually
meet these guidelines.
Some tasks have characteristics that require or preclude a specific execution policy. Tasks
that depend on other tasks require that the thread pool be large enough that tasks are never
queued or rejected; tasks that exploit thread confinement require sequential execution. Docu-
ment these requirements so that future maintainers do not undermine safety or liveness by
substituting an incompatible execution policy.
8.1.1. Thread Starvation Deadlock
If tasks that depend on other tasks execute in a thread pool, they can deadlock. In a single-
threaded executor, a task that submits another task to the same executor and waits for its
result will always deadlock. The second task sits on the work queue until the first task com-
pletes, but the first will not complete because it is waiting for the result of the second task.
The same thing can happen in larger thread pools if all threads are executing tasks that are
blocked waiting for other tasks still on the work queue. This is called threadstarvationdead-
lock , and can occur whenever a pool task initiates an unbounded blocking wait for some re-
source or condition that can succeed only through the action of another pool task, such as
waiting for the return value or side effect of another task, unless you can guarantee that the
pool is large enough.
ThreadDeadlock in Listing 8.1 illustrates thread starvation deadlock. Render-
PageTask submits two additional tasks to the Executor to fetch the page header and
footer, renders the page body, waits for the results of the header and footer tasks, and then
Search WWH ::




Custom Search