Skip to content

Commit 7daf667

Browse files
committed
Automatically dispose the context on JVM shutdown
And make the ThreadService's threads into daemon threads. The danger is that the such threads won't complete pending work. But with the JVM shutdown hook now attempting to dispose the context at that point, the ExecutorService will have a chance to shutdown cleanly.
1 parent 50daafb commit 7daf667

File tree

2 files changed

+11
-1
lines changed

2 files changed

+11
-1
lines changed

src/main/java/org/scijava/Context.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,9 @@ public Context(final Collection<Class<? extends Service>> serviceClasses,
290290
new ServiceHelper(this, serviceClasses, strict);
291291
serviceHelper.loadServices();
292292
}
293+
294+
// If JVM shuts down with context still active, clean up after ourselves.
295+
Runtime.getRuntime().addShutdownHook(new Thread(() -> doDispose(false)));
293296
}
294297

295298
// -- Context methods --

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,14 @@ public synchronized void dispose() {
173173
@Override
174174
public Thread newThread(final Runnable r) {
175175
final String threadName = contextThreadPrefix() + nextThread++;
176-
return new Thread(r, threadName);
176+
final Thread thread = new Thread(r, threadName);
177+
// NB: Use daemon threads for the thread pool, so that idling threads do
178+
// not prevent the JVM shutdown sequence from starting. The application
179+
// context, and therefore the thread service, will try to dispose itself
180+
// upon JVM shutdown, which will invoke executor.shutdown(), so there
181+
// will be a chance for these threads to complete any pending work.
182+
thread.setDaemon(true);
183+
return thread;
177184
}
178185

179186
// -- Helper methods --

0 commit comments

Comments
 (0)