Skip to content

Commit 418de99

Browse files
committed
ThreadService: improve thread safety
We now use double-checked locking for initialization. Otherwise, conceivably, two threads could trigger simultaneous creation of competing ExecutorServices. And we also synchronize the disposal, so that the ExecutorService cannot possibly be created after dispose() is called.
1 parent 96ae9be commit 418de99

File tree

1 file changed

+11
-5
lines changed

1 file changed

+11
-5
lines changed

src/main/java/org/scijava/thread/DefaultThreadService.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,12 @@ public ThreadContext getThreadContext(final Thread thread) {
141141
// -- Disposable methods --
142142

143143
@Override
144-
public void dispose() {
144+
public synchronized void dispose() {
145145
disposed = true;
146-
if (executor != null) executor.shutdown();
146+
if (executor != null) {
147+
executor.shutdown();
148+
executor = null;
149+
}
147150
}
148151

149152
// -- ThreadFactory methods --
@@ -157,12 +160,15 @@ public Thread newThread(final Runnable r) {
157160
// -- Helper methods --
158161

159162
private ExecutorService executor() {
160-
if (executor == null) {
161-
executor = Executors.newCachedThreadPool(this);
162-
}
163+
if (executor == null) initExecutor();
163164
return executor;
164165
}
165166

167+
private synchronized void initExecutor() {
168+
if (executor != null) return;
169+
executor = Executors.newCachedThreadPool(this);
170+
}
171+
166172
private Runnable wrap(final Runnable r) {
167173
final Thread parent = Thread.currentThread();
168174
return new Runnable() {

0 commit comments

Comments
 (0)