...
The following table shows a possible execution order:
Time | Task | Pool Thread | Submitted by Method | Day |
|---|---|---|---|---|
1 | t1 | 1 |
| Friday |
2 | t2 | 2 |
| Monday |
3 | t3 | 1 |
| Friday |
In this execution order, it is expected that the two tasks (t2 and t3) started from doSomething2() would observe the current day as Monday. However, because pool thread 1 is reused, t3 observes the day to be Friday.
...
| Code Block | ||
|---|---|---|
| ||
class CustomThreadPoolExecutor extends ThreadPoolExecutor {
public CustomThreadPoolExecutor(int corePoolSize,
int maximumPoolSize, long keepAliveTime,
TimeUnit unit, BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime,
unit, workQueue);
}
@Override
public void beforeExecute(Thread t, Runnable r) {
if (t == null || r == null) {
throw new NullPointerException();
}
Diary.setDay(Day.MONDAY);
super.beforeExecute(t, r);
}
}
public final class DiaryPool {
// ...
DiaryPool() {
exec = new CustomThreadPoolExecutor(NumOfthreads, NumOfthreads,
10, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10));
diary = new Diary();
}
// ...
}
|
Exceptions
TPS04-J-EX0: It is unnecessary to reinitialize a ThreadLocal object that does not change state after initialization. For example, there may be only one type of database connection represented by the initial value of the ThreadLocal object.
...
Objects using ThreadLocal data and executed by different tasks in a thread pool without reinitialization might be in an unexpected state when reused.
Rule | Severity | Likelihood |
|---|
Detectable | Repairable | Priority | Level |
|---|---|---|---|
TPS04-J | Medium | Probable | Yes |
No |
P8 |
L2 |
Bibliography
...
...