I have a Java application that will run on a IBM Liberty application server; I'm trying to use multithreading with the CICSExecutorService
. This is my use case:
CICSExecutorService
;CICSTransactionCallable
;This is the code:
CICSExecutorService cicsExecutorService = new CICSExecutorService();
//CICSReadingJob is the class that implements CICSTransactionCallable interface
CICSReadingJob<String> thread1 = new CICSReadingJob<>();
Future<List<String>> future1 = cicsExecutorService.submit(thread1);
cicsExecutorService.shutdown();
cicsExecutorService.awaitTermination(100, TimeUnit.SECONDS);
I have make some simple local tests with the standard java executor service and the behavior is that, after calling the shutdown and awaitTermination methods, the program waits for the threads termination (unless the execution of the threads takes more than 100 seconds, the specified timeout), and then the execution proceeds. The problem is that when I use the code above I see a different behavior: in fact, the program remains stuck on the awaitTermination
row for 100 seconds also if the thread ( the only one connected with the CICSExecutorService
) ends before (reaches the end of the call()
method). I also try to use the static method CICSExecutorService.runAsCICS()
instead of cicsExecutorService.submit()
, but I obtain the same result. It seems that the child thread remains alive also when it reaches the end of the call()
method, and for this reason the awaitTermination
waits until the end of the timeout. Any suggestions?
A CICSExecutorService instance is already provided internally by CICS. It is accessed directly from the static API methods such as the runAsCICS() method. You do not (and should not) attempt to construct the ExecutorService, or control the ExecutorService yourself - that is all done internally to ensure the correct environment and life-cycles are observed. There is a public constructor on the class purely to comply with Declarative Services requisites and not for general use. It looks like the the Javadoc should be more explicit about the intended use - I'll see if I can get that updated.
This page provides more details on how to use the API (albeit for a Runnable rather than a Callable, but the API follows the same pattern): https://www.ibm.com/support/knowledgecenter/SSGMCP_5.5.0/applications/developing/java/dfhpjgo.html
Note that you are submitting a 'Callable', not a thread, to the Executor. It is the CICSExecutorService which will decide in the background to run your callable on a 'CICS' enabled thread - allowing for thread pooling and re-use and other such smarts internally.
Also, if you are driving a CICS Liberty application, you should not usually need to spawn new CICS enabled threads yourself - the application will handle multiple, concurrent requests (typically web-requests) implicitly.
From the code snippet I cannot determine what your application is trying to achieve, but the Callable object which you submit should have it's call() method driven to completion, at which time the CICS task will end, and the thread on which it ran will be returned to the ExecutorService's thread-pool. The thread will remain dormant in that pool but no-longer associated with a CICS transaction (ready for re-use by another transaction). So if you are explicitly attempting to determine if the thread has terminated then you will be disappointed, they are not designed to terminate in the Liberty environment until the JVM server is disabled.
Typically when using the runAsCICS() method, you submit your Callable and get back a Future object. That Future object is then used to determine when the submitted work has completed. You should not attempt to wait for, or manipulate, the ExecutorService directly.
I hope that helps, but if you are still experiencing issues, please post more of the test-application and describe what you are trying to achieve so we can give better guidance. Thanks.