[
https://issues.apache.org/jira/browse/UIMA-6412?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Richard Eckart de Castilho resolved UIMA-6412.
----------------------------------------------
Resolution: Fixed
> Stop using ThreadGroup in CPMEngine
> -----------------------------------
>
> Key: UIMA-6412
> URL: https://issues.apache.org/jira/browse/UIMA-6412
> Project: UIMA
> Issue Type: Improvement
> Components: Collection Processing
> Reporter: Richard Eckart de Castilho
> Assignee: Richard Eckart de Castilho
> Priority: Major
> Fix For: 3.3.0SDK
>
>
> The {{CPMEngine}} internally uses a {{ThreadGroup}} to manage the worker
> threads. This causes a problem with concurrency features present in modern
> Java versions, e.g. the static system-wide {{ForkJoinPool.commonPool()}}
> which is used by concurrency features by default when no other pool is
> specified. But even if a custom pool is used, the problem persists. The
> problem is that threads launched from within the context of a thread that is
> part of a thread group inherits that thread group as its parent.
> Consequently, worker threads launched e.g. by the
> {{ForkJoinPool.commonPool()}} become part of the CPM thread group. The common
> pool worker threads are long-lived and re-used. the CPM thread group however
> refuses to shut down as long as there are still threads in it. That
> essentially blocks the use of many concurrency features within the scope of a
> CPE.
> The best approach would probably be to replace the {{CPMThreadGroup}} with
> some kind of {{CPMExecutorService}} which essentially performs the same
> duties as the thread group but without being a thread group.
> * {{CPMThreadGroup.uncaughtException()}} - instead of handling the uncaught
> exceptions at the level of the thread group, an exception handler needs to be
> installed in the individual spawned threads
> * {{ThreadGroupDestroyer}} - this is the code that currently waits until all
> threads in the {{CPMThreadGroup}} are finished and then destroys the group to
> avoid {{CPMThreadGroup}}-instances piling up over time. I guess the
> replacement would be to call {{shutdown()}} on the replacement executor
> service. {{shutdown()}} causes the executor service not to accept any new
> tasks and once all running tasks are done, it cleans itself up.
> * worker threads must not be started by callling {{start()}} explicitly but
> rather by submitting them to the executor service
> * The CPE allows configuring a custom output queue (instance of
> {{BoundedWorkQueue}}. There is one subclass of {{BoundedWorkQueue}} provided
> by UIMA which is the {{SequencedQueue}} and it internally spawns a new
> {{ExpirationTimer}} thread. In the current implementation, this timer thread
> would block the thread group from shutting down. However, the task of the
> {{ExpirationTimer}} is just to remove a map entry after a certain amount of
> time - it is not a long running thread. So I think that it doesn't matter
> that it won't block the execution service from shutting down and also that we
> do not have to change the API for registering custom output queues to pass
> the execution service into the custom queues. There might be custom queues
> which rely on the thread group being blocked, but I somewhat doubt it - and
> if so, those will then have to change their implementation... I'd still call
> this a feature release change and not a major release change.
> * This removes the public {{CPMThreadGroup}} class and replaces it with a
> {{CPMExecutorService}}. Again this is a change of an API that is in principle
> public and such changes should only be done in major releases. But again, I
> doubt that anybody really depends on this particular API. I think it is
> mainly public because the class is used by another class in a different
> package and otherwise it should be considered internal. So - IMHO - fine for
> a feature-level release.
--
This message was sent by Atlassian Jira
(v8.20.1#820001)