...
The execution order may differ depending on thread scheduling, however, Friday occurs just once in this case. Note that increasing the thread pool size from time to time is not a feasible option.
Compliant Solution (try-finally
clause)
This compliant solution wraps the statements in the doSomething1()
method of class DiaryPool
in a try-finally
block. The finally
block restores the initial state of the thread local object days
.
Code Block | ||
---|---|---|
| ||
public final class DiaryPool {
// ...
public void doSomething1() {
exec.execute(new Runnable() {
public void run() {
try {
Diary.setDay(Day.FRIDAY);
diary.threadSpecificTask();
} finally {
Diary.setDay(Day.MONDAY);
}
}
});
}
// ...
}
|
This solution transfers the burden of maintainability to the client but is a good option when the Diary
class cannot be refactored.
Compliant Solution (instance per call)
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 static 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 ...
System.out.println("The day is: " + currentDay());
}
}
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
}
}
|
...