UML软件工程组织

设计Java实时多任务调度的安全监控(1)
作者:方浩波 本文选自:IBM DW中国 2002年12月05日

在一系列关联的多任务的实时环境中,如果有一个任务发生失败,可能导致所有任务产生连锁反应,从而造成调度失控的局面。特别是对于核心控制设备尤其重要,为了解决这个问题,必须对每个任务进行实时监控。

问题分析

在JAVA环境中,一个任务一般是由一个独立线程来引导实现的,独立线程可能调用一系列子线程。如果在执行过程中,某一个线程发生异常(产生的原因很多,比如软件升级、运行环境改变、系统资抢占等),那么该线程就会停止运行,直到下次任务重新被提交。对于实时环境来说当前任务是失败的。我们无法预测和完全避免异常的发生,但是可以通过一些技术手段来跟踪任务的状态,从而及时发现问题并恢复正常,减少损失。

设计原理

对于一个实时任务而言,执行效率是非常关键的,这意味着不可能考虑用非常复杂的方式来实现任务监控,即使这样可以做的比较完善,同时监控代码本身也会引入一些异常,这就要求监控程序必须简单可靠,能够发现大多数问题,并能及时处理。

一个可能的简单实现

我们对每个任务加上一个监控的“壳”,调度程序调用这个“壳”来完成对具体任务的引导和监控,相当于每个任务具有自治能力。这样做的好处有:

1. 分散控制。不需要修改调度主体程序,不增加调度过程的复杂度;

2. 控制灵活,安全性高。对于不同任务可定义不同控制方式和控制参数,封装在任务内部,灵活性好,对个别任务控制代码的修改不会影响其他任务,即任务控制实现松藕合,避免错误扩散。适合团队开发;

3. 维护简单,升级方便。对于新的任务加入也无需改变原来调度程序的结构,只需修改任务表及相关参数,这样在性能提高的同时也简化了软件升级过程中的代码维护量。

设计实现

每个线程理论上有四种状态:

new 线程对象已经创建,但尚未启动,不可运行
runnable 一旦有时间分片机制有空闲的CPU周期,线程立即开始运行
dead 从run()方法退出后,一个线程即消亡
blocked    线程可运行,但有某种东西阻碍了它。调度机制不给它分配任何CPU时间,直到它进入runnable状态

在实际操作中,为了便于描述,我们重新规定了线程的状态:

Actived 线程已被激活,处于运行状态
Sleeping 线程完成一个特定任务后退出,进入休眠状态
Dead 线程运行过程中发生异常,终止运行,处于死亡状态

根据上述理论,我们只需要对Actived状态的线程进行监控,也只有对Actived状态监控才有意义,这是对监控模块做出逻辑简化。那么如何实现监控模块对具体任务的监控呢?



版权所有:UML软件工程组织