CICS 任务和线程管理

CICS® 使用开放事务环境 (OTE) 运行 JVM 服务器工作。 CICS 启用 JVM 服务器时,会创建一个 TP TCB 作为新 Language Environment® (LE) 进程的父进程。 然后,将在 LE 初始进程线程 (IPT) 下启动 JVM。

当 CICS 任务链接到 Java PROGRAM 或启动 Java PROGRAM 时,该任务会切换到启用了 CICS 的线程(称为 CICS T8 TCB )上。 T8 TCB 将连接到能够运行 Java 并进行 JCICS (EXEC CICS) 调用的 JVM。

您可以通过在 JVMSERVER 资源上设置 THREADLIMIT 属性来控制可供 JVM 服务器使用的 T8 TCB 数。 T8 为 JVM 服务器创建的 TCB 存在于虚拟池中,不能由另一个 JVM 服务器复用。 在所有 JVM 服务器中, CICS 区域中可以存在的 T8 TCB 的最大数目为 2000 ,而特定 JVM 服务器的最大数目为 256。

当启用 OSGi 或 Liberty JVM 服务器时,它还会启动 CJSL 事务以创建称为 JVM 服务器侦听器的长时间运行的任务。 此侦听器等待来自应用程序的新线程请求,并在响应中创建在 T8 TCB 上分派的新 CICS 任务。 下图中显示了此过程:

图 1。 应用程序的多线程
此图显示了正在 OSGi 框架中运行的 Java 应用程序接收的进入 CICS 区域的应用程序请求。 应用程序创建线程,线程侦听器在 T8 TCB 上启动新任务并运行 JCICS 以访问 VSAM。

JVM 服务器的执行密钥

在 JVM 服务器中运行的 Java 程序必须在执行键 CICS中运行。 要确保指定正确的密钥,请定义 Java PROGRAM 资源以将 EXECKEY 属性设置为 CICS。 Java 程序运行时,将在 T8 TCB 下运行,并获取 CICS key 中的 MVS 存储空间。

启动新的 Java 线程

在 OSGi 或 Liberty JVM 服务器中运行的 Java 应用程序可以异步启动新线程。 要在新的 CICS 任务下运行此线程, Java 代码需要实现 java.util.concurrent 包中提供的 CallableRunnable 接口。 Callable 接口表示可以在单独的 Java 线程上异步执行的新工作,并且必须返回 Object。 Java Runnable 接口类似,但它不会向调用者返回值。

要在新的 CICS 任务下运行,并访问 CICS API 和服务,如 JCICS 和 Db2® 与类型 2 JDBC 的连接,必须将 CallableRunnable 提交给适当的 Java 执行器服务。 在 OSGi JVM 服务器中, CICS 提供可从 OSGi 服务注册表中查找的执行程序服务。 或者,可以将工作提交到 CICSExecutorService,这是 JCICS API 的一部分。 该 API 将自动查找 CICS 执行程序实现,并在新任务下使用启用了 CICS的线程启动工作。
注: 使用 Java SE Thread.start 机制创建的标准 Java 线程不使用 CICS 提供的执行程序服务,并且无权访问 CICS API 和服务。
在 CICS Liberty 中, CICS 将标准 Liberty ThreadFactory 替换为提供 CICS支持的线程的 CICS 实现。 将在后续拦截点检查入局请求,这将确定是否将创建新的 CICS 任务。 最初未与 CICS 任务关联的线程随后可以调用 JCICS API ,此时将调用 CICS 延迟绑定机制以确保该线程连接到新的 CICS 任务。 通过现有工作负载,您可以通过向 Liberty 的受管执行程序服务 (通过使用 Liberty concurrent-1.0 功能部件启用) 提交请求来启动进一步的异步操作。
您知道吗: 在 Liberty JVM 服务器中启动新的 Java 线程时,新的 CICS 任务可能直到首次使用 JCICS API 后才会绑定到该线程。 这称为 延迟绑定
下表总结了使用不同执行程序服务实现时 Liberty 和 OSGi JVM 服务器中对 JCICS 的支持:
表 1. OSGi 和 Liberty JVM 服务器的执行程序服务实现
Executor 服务实现 OSGi JVM 服务器 Liberty JVM 服务器
JCICS CICSExecutorService 对 JCICS 的支持 对 JCICS 的支持
企业 Java ManagedExecutorService 不可用 对 JCICS 的支持

JVM 服务器中的不可恢复错误

当发生导致 JVM 意外停止的错误时,将通知 CICS JVM 服务器基础结构该错误,并使用 PURGETYPE(PHASEOUT)触发 DISABLE 。 根据 JVM 中的当前工作负载, CICS 可能无法完全 DISABLE JVM 服务器。

如果 JVM 服务器未在升级超时内停止,那么自发出先前的 DISABLE 命令以来, CICS 将再次触发 DISABLE 。 每次达到升级超时时, CICS 都会移至下一个 PURGETYPE,通过 PHASEOUTPURGEFORCEPURGE工作到 KILL

如果升级使用 PURGETYPE(PURGE)PURGETYPE(FORCEPURGE)运行 DISABLE ,那么可能会清除连接到 JVM 服务器的任何 CICS 任务。 将向 JVM 中运行的任何 Java 线程发送停止请求,并且可能会收到java.lang.ThreadDeath出错。

PURGETYPE(KILL)如果升级运行的是 DISABLE ,则运行 JVM 的 Language Environment enclave 会被停止。 任何连接到 JVM 服务器的 CICS 任务都会终止并进入恢复处理。

当 JVM 服务器因该进程而停止并达到 DISABLED 状态时,它会自动重启,回到 ENABLED 状态,提供一个新的、干净的 Language Environment enclave 和 JVM,随时准备处理请求。

导致 JVM 停止的错误通常涉及使用 Java 本机接口 (JNI) 的代码中的错误,或者 JVM 进程接收到 POSIX 信号时的错误。 错误可能由用户代码或 JVM 基础结构代码引起。

SIGABRT 信号会导致 JVM 服务器停止并重新启动,并且 CICS 会生成 DFHSJ1011 消息。 CICS 生成以下信号的诊断信息: SIGHUPSIGABRTSIGILLSIGINTSIGFPESIGBUSSIGSEGVSIGTERM

此外, SIGKILL 信号会导致 JVM 服务器停止并重新启动,并给出 DFHSJ0005 消息。

注: SIGQUIT 信号用于从 JVM 生成诊断信息,不会导致 JVM 服务器禁用并重新启动。

失控任务

CICS JVM 服务器基础结构支持使用任务失控检测机制。 与传统 CICS 任务不同,在 T8 TCB 上运行 Java 的任务不能在对同一 JVM 中的其他工作负载造成影响的情况下终止。 Language Environment 和 JVM 服务器在 兼容的环境中运行,该环境规定,如果 TCB 或线程被终止,父进程也会被终止。 POSIX 反过来,所有子进程会突然终止-并导致 JVM 中的所有任务立即失败。

在 JVM 服务器中运行的超出修改后的 RUNAWAY 时间间隔的任务迂到更受控的终止过程。 这与传统的 CICS 行为不同,您应该评估是要将失控时间间隔应用于 Java 任务,还是要设置哪些值。
JVMSERVER 受控失控处理
当运行 Java 的任务迂到失控时间间隔条件时, JVMSERVER 将拦截该条件并触发 DISABLE PHASEOUT。 将阻止新工作进入 JVM ,并使现有工作放弃。 随后,如果任务完成其处理,那么 JVMSERVER 将重新启用并可用于新请求。 在许多情况下,如果运行 Java 的任务超过失控的时间间隔值,那么它可能是错误的应用程序 (例如,紧循环的应用程序) ,并阻止 JVMSERVER 的 PHASEOUT/RECYCLE 成功。 检测到应用程序时,失控计时器将在另一个时间间隔后再次触发,并且 JVMSERVER DISABLE PHASEOUT 将升级到 JVMSERVER DISABLE PURGE。 其余任务将接受 PURGE 处理,并且在大多数情况下将终止。 如果超过进一步的失控时间间隔,那么 JVMSERVER DISABLE 会升级到 FORCEPURGE ,并最终升级到 KILL ,直到强制终止所有正在运行的任务为止。 JVMSERVER 会重新启动回 ENABLED 状态,以便为新请求做好准备。
修改后的失控区间值
在 JVM 服务器中运行的任务的失控情况可能导致整个 JVM 服务器的临时可用性问题。 因此, CICS 通过将配置的失控时间间隔值乘以 10 (最大值为 45 分钟) 来修改该值。 此新值是有效失控时间间隔。 此较高的失控时间间隔降低了检测到低效 (但以其他方式工作) 应用程序的失控情况的可能性。 例如,如果事务定义指定 RUNAWAY=SYSTEM,并且 ICVR 系统初始化参数指示缺省限制为 5000 毫秒,那么该任务在 JVM 服务器中运行时的有效失控时间间隔为 50000 毫秒。
设置失控间隔值
缺省情况下,用于 Liberty JVM 服务器的 CJSA 事务定义以及用于从 CICSExecutorService 启动的 OSGi JVM 服务器中的工作的 CJSA 事务定义已激活失控检测并设置为系统时间间隔。 如果您不希望失控时间间隔应用于这些任务,那么可以在自己的事务定义下运行工作,并且失控时间间隔设置为 0 或您选择的其他值。 Liberty 工作负载通常由 URIMAP 控制,而 CICSExecutorService 提供 CICSTransactionRunnableCICSTransactionCallable 接口以允许使用定制事务定义。