CICS task and thread management

CICS® uses the open transaction environment (OTE) to run JVM server work. When CICS enables a JVM server, it creates a TP TCB as the parent of a new Language Environment® (LE) process. The JVM is then started under the LE initial process thread (IPT).

When a CICS task links to, or starts a Java PROGRAM, the task switches onto a CICS-enabled thread known as a CICS T8 TCB. The T8 TCB is attached to the JVM where it is capable of running Java and making JCICS (EXEC CICS) calls.

You can control how many T8 TCBs are available to the JVM server by setting the THREADLIMIT attribute on the JVMSERVER resource. T8 TCBs that are created for the JVM server exist in a virtual pool and cannot be reused by another JVM server. The maximum number of T8 TCBs that can exist in a CICS region across all JVM servers is 2000 and the maximum for a specific JVM server is 256.

When an OSGi or Liberty JVM server is enabled, it also starts the CJSL transaction to create a long-running task called the JVM server listener. This listener waits for new thread requests from the application and in response creates new CICS tasks that are dispatched on a T8 TCB. This process is shown in the following diagram:

Figure 1. Multi-threading of applications
Diagram showing an application request that is coming into a CICS region, being received by a Java application that is running in an OSGi framework. The application creates a thread, the thread listener starts a new task on a T8 TCB and runs JCICS to access VSAM.

Execution keys for JVM servers

Java programs that run in a JVM server must run in execution key CICS. To ensure the correct key is specified, define your Java PROGRAM resources to have the EXECKEY attribute set to CICS. When the Java programs runs, it will run under a T8 TCB and obtain MVS storage in CICS key.

Starting new Java threads

Java applications that are running in an OSGi or Liberty JVM server can start new threads asynchronously. To run this thread under a new CICS task, the Java code needs to implement either the Callable or Runnable interfaces that are provided in the java.util.concurrent package. The Callable interface represents new work that can be executed asynchronously on a separate Java thread, and must return an Object. The Java Runnable interface is similar, but it does not return a value to the caller.

To run under a new CICS task and gain access to CICS API and services such as JCICS and Db2® with type 2 JDBC connectivity, the Callable or Runnable must be submitted to an appropriate Java executor service. In an OSGi JVM server, CICS supplies an executor service, which you can look up from the OSGi service registry. Alternatively, work can be submitted to the CICSExecutorService, which is part of the JCICS API. The API will find the CICS executor implementation automatically and start the work using a CICS-enabled thread under a new task.
Note: Standard Java threads created by using the Java SE Thread.start mechanism do not use the CICS supplied executor service, and do not have access to CICS API and services.
In CICS Liberty, CICS replaces the standard Liberty ThreadFactory with a CICS implementation that provides CICS-enabled threads. Incoming requests are inspected at a subsequent intercept point, which determines whether a new CICS task will be created. Threads that are not initially associated with a CICS task can subsequently call the JCICS API, and at that time the CICS late-binding mechanism will be invoked to ensure the thread is attached onto a new CICS task. From an existing workload, you can start further asynchronous operations by submitting requests to Liberty's managed executor service, which is enabled by using the Liberty concurrent-1.0 feature.
Do you know: When a new Java thread is started in a Liberty JVM server, a new CICS task might not be bound to the thread until the first use of the JCICS API. This is referred to as late-binding.
The following table summarizes the support for JCICS in Liberty and OSGi JVM servers when using the different executor service implementations:
Table 1. Executor service implementations for OSGi and Liberty JVM servers
Executor service implementation OSGi JVM server Liberty JVM server
JCICS CICSExecutorService Support for JCICS Support for JCICS
Enterprise Java ManagedExecutorService Not available Support for JCICS

Unrecoverable errors in JVM servers

When an error occurs that causes the JVM to stop unexpectedly, the CICS JVM server infrastructure is notified of the error and triggers a DISABLE with PURGETYPE(PHASEOUT). Depending on the current workload in the JVM, CICS might not be able to cleanly DISABLE the JVM server.

If the JVM server does not stop within the escalation timeout, since the previous DISABLE command was issued, CICS triggers a DISABLE again. Each time the escalation timeout is reached, CICS moves to the next PURGETYPE, working through PHASEOUT, PURGE, FORCEPURGE, to KILL.

If the escalation runs a DISABLE with PURGETYPE(PURGE) or PURGETYPE(FORCEPURGE), any CICS tasks that are attached to the JVM server might be purged. Any Java threads running in the JVM are sent a request to stop, and might receive a java.lang.ThreadDeath error.

If the escalation runs a DISABLE with PURGETYPE(KILL), the Language Environment enclave in which the JVM is running is stopped. Any CICS tasks that are attached to the JVM server abend and enter recovery processing.

When the JVM server stops and reaches a DISABLED state due to this process, it is automatically restarted, returning to an ENABLED state, providing a new, clean Language Environment enclave and JVM, ready to process requests.

Errors that cause the JVM to stop typically involve an error in code that uses the Java Native Interface (JNI), or when a POSIX signal is received by the JVM process. Errors can be caused by either user code, or by the JVM infrastructure code.

The SIGABRT signal causes the JVM server to be stopped and restarted, and CICS produces a DFHSJ1011 message. CICS produces diagnostic information for the following signals: SIGHUP,SIGABRT, SIGILL, SIGINT, SIGFPE, SIGBUS, SIGSEGV, and SIGTERM.

Additionally, the SIGKILL signal causes the JVM server to be stopped and restarted and gives a DFHSJ0005 message.

Note: The SIGQUIT signal is used to produce diagnostic information from the JVM, and does not cause the JVM server to disable and restart.

Runaway tasks

The CICS JVM server infrastructure supports use of the task runaway detection mechanism. Unlike traditional CICS tasks, a task running Java on a T8 TCB cannot be terminated without consequences to other workload in the same JVM. Language Environment and the JVM server run in a POSIX-compliant environment, which mandates that if a TCB or thread is terminated, the parent process is also terminated. In turn, all child processes are terminated abruptly–and cause all tasks in the JVM to fail immediately.

A task running in a JVM server that exceeds the modified RUNAWAY interval experiences a more controlled termination process. This differs from the traditional CICS behavior and you should evaluate whether you want runaway intervals to apply to your Java tasks, or what value to set.
JVMSERVER controlled runaway processing
When a task running Java experiences a runaway interval condition, the JVMSERVER intercepts the condition and triggers a DISABLE PHASEOUT. New work is prevented from entering the JVM and existing work is left to drain. Subsequently, should the task complete its processing, the JVMSERVER re-enables and becomes available for new requests. In many cases, if a task running Java exceeds the runaway interval value, it is likely to be a bad application, such as a tightly looping application, and prevents successful PHASEOUT/RECYCLE of the JVMSERVER. When an application is detected, the runaway timer triggers again after another interval and the JVMSERVER DISABLE PHASEOUT is escalated to a JVMSERVER DISABLE PURGE. Remaining tasks are subject to PURGE processing and in most cases are terminated. If further runaway intervals are exceeded, the JVMSERVER DISABLE escalates to FORCEPURGE and ultimately KILL until all running tasks are forcefully terminated. The JVMSERVER recycles back to the ENABLED state ready for new requests.
Modified runaway interval value
A runaway condition for a task that is running in a JVM server can cause temporary availability problems for the whole JVM server. For this reason, CICS modifies the runaway interval value that was configured, by multiplying it by a factor of 10 (up to a maximum value of 45 minutes). This new value is the effective runaway interval. This higher runaway interval reduces the possibility of a runaway condition being detected for an inefficient (but otherwise working) application. For example, if the transaction definition specifies RUNAWAY=SYSTEM, and the ICVR system initialization parameter indicates a default limit of 5000 milliseconds, then the effective runaway interval for that task when it runs in a JVM server is 50000 milliseconds.
Setting the runaway interval value
By default the CJSA transaction definition that is used for Liberty JVM servers and for work in an OSGi JVM server started from the CICSExecutorService has runaway detection active and set to the system interval. If you do not want runaway intervals to apply to these tasks, you can run work under your own transaction definitions with the runaway interval set to 0, or another value of your choice. Liberty workload is typically controlled by URIMAPs, while the CICSExecutorService provides the CICSTransactionRunnable and CICSTransactionCallable interfaces to allow customized transaction definitions to be used.