uima-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Timo Boehme (JIRA)" <...@uima.apache.org>
Subject [jira] [Commented] (UIMA-1906) Daemon thread prevents CPE exit
Date Mon, 01 Feb 2016 15:08:40 GMT

    [ https://issues.apache.org/jira/browse/UIMA-1906?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15126363#comment-15126363

Timo Boehme commented on UIMA-1906:

Typically we run into the daemon thread issue when data resources are initialized lazily like
a database access only needed at specific circumstances. It is common with some database drivers
(e.g. Derby in application mode) that a daemon thread is started for monitoring/cleanup work
which is still running even when the connection is closed. Since these threads are marked
daemon it is supposed that they should not block a system shutting down.

The patch adds very little overhead to the current implementation since thread enumeration
was already called (even if the information wasn't used at all). It uses a defined maximum
time span to allow for daemon threads to shutdown (after all other non-daemon threads stopped).
If after this time there are still daemon threads it at least sets the group to be a daemon
group, signaling the Java VM to release resources as soon as possible.
The main difference to the previous implementation is that it now won't block forever but
allows the CPE to shutdown if only daemon threads are left.

I would appreciate it if the patch or a similar working solution could be added to UIMA. This
would facilitate a more predictable shutdown behavior, especially if 3rd party software is
integrated which might run daemon threads and cannot be controlled in how this is done.

> Daemon thread prevents CPE exit
> -------------------------------
>                 Key: UIMA-1906
>                 URL: https://issues.apache.org/jira/browse/UIMA-1906
>             Project: UIMA
>          Issue Type: Bug
>          Components: Collection Processing
>    Affects Versions: 2.3
>            Reporter: Timo Boehme
>         Attachments: CPMEngine.diff, cpm_messages.diff
> If a daemon thread was started within an AE and keeps running independent of the AE processing
(e.g. bound to a static variable) it prevents exiting of the CPE.
> Simple test:
> add following class to a AE:
> static class DaemonThread implements Runnable {
> 	private static volatile Thread threadInstance;
> 	/** Creates a daemon thread if it not already exists. */
> 	public synchronized static void startThread() {
> 		if ( threadInstance == null ) {
> 			threadInstance = new Thread( new DaemonThread(), "TestDaemon" );
> 			threadInstance.setDaemon( true );
> 			threadInstance.start();
> 		}
> 	}
> 	@Override
> 	public void run() {
> 		while ( true ) {
> 			try { Thread.sleep( 2000 ); } catch ( InterruptedException ie ) {}
> 		}
> 	}
> }
> and call DaemonThread.startThread(); within the process() method.
> After CPE signals collectionProcesscomplete() the application does not exit.
> The reason: in org.apache.uima.collection.impl.cpm.engine.CPMEngine a threadGroupDestroyer
thread is created (line 2522) which waits for threads to die. Since it does not check for
daemon threads it counts them as normal threads to wait for and thus it waits forever (this
can be seen with kill -3 PID to get a JAVA stack trace of all threads under UNIX).
> A workaround would be to put the daemon thread in another ThreadGroup. In the example
if you create the tread with
> 			ThreadGroup parent = Thread.currentThread().getThreadGroup();
> 			while ( parent.getParent() != null )
> 				parent = parent.getParent();
> 			threadInstance = new Thread( parent, new DaemonThread(), "TestDaemon" );
> (in the top most thread group)  the CPE exits normally.
> However this is not possible with closed source libraries.
> Thus the threadGroupDestroyer must test for daemon threads. Furthermore the used group.activeCount()
(in org.apache.uima.collection.impl.cpm.engine.CPMEngine) should only be used for information
purposes - as the javadoc states - not for relying on it as a loop parameter.

This message was sent by Atlassian JIRA

View raw message