Wiki Markup |
---|
According to the Java API class {{java.lang.ThreadLocal<T>}} documentation \[[API 06|AA. Java References#API 06]\], class {{java.lang.ThreadLocal<T>}} documentation: |
This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its
get
orset
method) has its own, independently initialized copy of the variable. ThreadLocal instances are typicallyprivate static
fields in classes that wish to associate state with a thread (e.g., a user ID or Transaction ID).
...
The following table shows a possible execution order:
Time | /Thread# | Pool Thread | Submitted By Method | Day |
---|---|---|---|---|
1 | t1 | 1 |
| Friday |
2 | t2 | 2 |
| Monday |
3 | t3 | 1 or 2 |
| Friday |
In this execution order, the two threads (2 t1 and 3 t1) started using doSomething2()
are expected to see the current day as Monday, however, one of them (thread t3) inherits the day Friday from the first thread (thread t1), when that thread is reused.
...
This solution transfers the burden of maintainability to the client (DiaryPool
) but is a good option when the Diary
class cannot be refactored.
...
The class Diary
does not use a ThreadLocal
object in this compliant solution. Also, the class DiaryPool
uses local instances of class Diary
within the methods doSomething1()
and doSomething2()
. The Day
is uniquely maintained by each instance of the Diary
class. As multiple threads are allowed to share a Diary
instance, the day
field is declared static
. Creating two Diary
instances in class DiaryPool
allows the first thread to work with the object instance having the current day as Friday and the other two threads to work with the object instance having the current day as Monday.
Code Block | ||
---|---|---|
| ||
public final class Diary { private staticvolatile Day day; Diary() { day = Day.MONDAY; // Default } private Day currentDay() { return day; } public void setDay(Day d) { day = d; } // Performs some thread-specific task public void threadSpecificTask() { // Do task ... } } public final class DiaryPool { private final int NoOfThreads = 2; // Maximum number of threads allowed in pool private final Executor exec; DiaryPool() { exec = (Executor) Executors.newFixedThreadPool(NoOfThreads); } public void doSomething1() { final Diary diary = new Diary(); // First instance exec.execute(new Runnable() { public void run() { diary.setDay(Day.FRIDAY); diary.threadSpecificTask(); } }); } public void doSomething2() { final Diary diary = new Diary(); // Second instance exec.execute(new Runnable() { public void run() { diary.threadSpecificTask(); } }); } public static void main(String[] args) { DiaryPool dp = new DiaryPool(); dp.doSomething1(); // Thread 1, requires current day as Friday dp.doSomething2(); // Thread 2, requires current day as Monday dp.doSomething2(); // Thread 2, requires current day as Monday } } |
Creating two Diary
instances in class DiaryPool
allows the first thread to work with the object instance having the current day as Friday and the other two threads to work with the object instance having the current day as Monday.
The following table shows a possible execution order that conforms to the requirements:
Time | /Thread# | Pool Thread | Submitted By Method | Day |
---|---|---|---|---|
1 | t1 | 1 |
| Friday |
2 | t2 | 2 |
| Monday |
3 | t3 | 1 or 2 |
| Monday |
Classes that cannot be refactored and whose design incorporates ThreadLocal
data should not be executed in thread pools.
Exceptions
EX1: Sometimes the state of the ThreadLocal
object does not change beyond its initial value. For example, there may be only one type of database connection represented by the initial value of the ThreadLocal
object. In the absence of mutability, it is safe to use a thread pool.
...
When objects of classes that use ThreadLocal
data are executed in a thread pool by different threads, they may assume stale statesthe objects might acquire stale values, resulting in corrupt datastate.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
CON27- J | high | probable | medium | P12 | L1 |
...