logo资料库

论文研究-Java多线程测试策略及测试方法探讨.pdf

第1页 / 共3页
第2页 / 共3页
第3页 / 共3页
资料共3页,全文预览结束
·21· 计算机应用研究 2006 年 Java 多 线 程 测 试 策 略 及 测 试 方 法 探 讨 * ( 1. 解放 军信 息工 程大 学 测绘 学院, 河南 郑州 450052; 2. 河 南工业 大学 计 算机 科学 系, 河 南 郑州 450052) 张雪萍 1, 2 , 鲍 丹2 , 王家耀 1 摘 要: 在 分析 Java 多 线程 特性 的基础 上, 探 讨了 Java 多线 程的 测试 策略 及测 试方 法, 提出 Java 多 线 程测 试 由 类测 试、集成 模块 测试 和系 统测 试三个 层次 组成 , 并 讨论 了多 线程 的继 承测 试、同步 测试 以及 效率 测试 。 关键 词: Java 多线 程; 测 试策 略; 继 承测 试; 同 步测 试; 效 率测 试 中图 法分 类号 : TP311 文章 编号 : 1001- 3695( 2006) 11- 0012- 03 文献 标识码 : A Research on Testing Strategies and Methods for Java Multithread ( 1. Institute of Surveying & Mapping, PLA Information Engineering University, Zhengzhou Henan 450052, China; 2 . Dept. of Computer Sci- ence, Henan University of Technology, Zhengzhou Henan 450052, China) ZHANG Xue-ping1, 2, BAO Dan2, WANG Jia-yao1 Abstract: Based on analyzing the features of Java multithread, testing strategies and methods are discussed in this paper. Ja- va multithread testing is consist of class testing, integration block testing and systemtesting. The main testing methods for Java multithread are proposed, such as inherit testing, synchronization testing and synchronization efficiency testing. Key words: Java Multithread; Testing Strategies; Inherit Testing; Synchronization Testing; Efficiency Testing 面向对象软件测试是面向对象开发方法不可缺少的一环, 是保证软件质量、提 高软件 可靠性 的关 键。近年 来, 随着 Java 语言的广泛应用, 针 对 Java 的软 件测 试已 成为 软件 工程 领 域 中的一个重要 研究 课 题, 国内 外 研究 机构 不 断推 出 各 种 Java 软件测试工具, 如 Junit[ 1] , Cactus, JMeter, Safepro /Java 等。 Java 的多线程机制使应用程序能够并行执行, 而且同 步机 制保证了对共享数据的正确操作。通过使用多线程, 程序设计 者可以分别用不同的线程完成特定的行为, 而不需要采用全局 的事件循环机制, 这样就 很容易 实现网 络上的 实时交 互行为。 多线程带来的最大好处是更好的交互性能和实时控制性能。 Java 多线程广泛应用于 网络, 在当 今的网 络环 境下, 研 究 对于 Java 多线程的测试是很有必要的。从 现有公开 发表的 国 内外文献来 看, 专 门 针对 Java 多线 程 软 件 测 试 的 研 究不 多。 国内方艳等人在文献[ 2] 中介绍了 Safepro/ Java 的 多线程测 试 技术, 其他深入、具体的研究还未见报道。 1 Java 多线程特点 Java 作为 一 种 纯 面 向 对 象 语 言, 其 优 越 性 是 不 言 而 喻 的 [ 3, 4] 。 1. 1 Java 多线程继承 由于 Java 引入了“包”的概念, 从而使类的继 承更加简便, 线程的创建是一个最好 的例子。Java 多线 程的实 现方 法有 两 收稿日期: 2005- 09- 09; 修返日期: 2005- 11- 12 基金项目: 国 家自 然 科学 基金 资 助项 目 ( 69873040) ; 河 南 省 自然科学基金资助项目( 0511011000) ; 河南省高校青年骨干教 师 资 助 项 目; 河 南 省 教 育 厅 自 然 科 学 基 础 研 究 项 目 ( 2003520260) ; 河南工业大学基础研究项目( 0402003) 种: ①通过 Thread 继承。为创建一个 线程, 最 简单的 方法就 是 从 Thread 类继承。②通过 Runnable 接口。该方式主要是用 来 实现特殊功能, 如复杂的多重继承功能等。Runnable 接口的 应 用虽然提高了软件开发 的灵活 度, 但 是同 时也 是造 成 BUG 的 根源之一 [ 3, 4] 。 1. 2 Java 多线程同步 Java 应用程序的多个线程共享同一进程的数据资源, 多 个 用户线程在并发运行过程中可能同时访问具有敏感性的内容。 在 Java 中定义了线 程同 步的 概念, 实 现对共 享 资源 的一 致 性 维护。线程同步是多线程编程的一个非常重要的技术。 1. 3 Java 多线程消息控制 Java 多线程的另外一个特点就是可以实现进程间的通信。 进程间的通信是以消息为形式的, 如何进行消息的控制是多线 程设计的一个重点。 1. 4 Java 多线程流程控制 Java 线程之间的通信机制 由线程 同步和 消息 控制 共同 作 用。Java 多线程流程控制中既涉及到了多线程继承的问题, 又 涉及到同步控制和消息控制 [ 5] 。 多线程流程控制方法有以下几个: ( 1) 通过 sleep( ) 来实 现 Java 多 线程 流程 控制, 可 以用 于 多线程流程控制演示。 ( 2) 通过 interrupt( ) 函数对 Java 多线程进行流程控制。这 种控制方法比 sleep( ) 函 数要精确得 多, 但在用 法上与 sleep( ) 函数不太相同。 ( 3) 通过 wait( ) 和 notify( ) 来进 行流程 控制。wait( ) 方 式 与 sleep( ) 方式有相同 之处, 都是 从线程 内部对 线程进 行中 断 的; 不同的是, 它没有提供中断 时间, 其唤 醒方式 就是 notify( ) 和 notifyAll( ) 。
第 11 期 张雪萍等: Java 多线程测试策略及测试方法探讨 ·31· ( 4) 通过 join( ) 来进行流程控 制, join( ) 方式 结合了 inter- rupt 和 sleep 方式的优点。在实际设计当 中应注意使 用 join 方 式的时机, 过多的 join 方式会打乱线程的流程。 2 Java 多线程测试策略 2. 1 层次划分 对于传统程序设计语言书写的软件, 软件测试人员普遍接 受三个级别的测试, 即单元 测试、集成测 试和系 统测试。对 面 向对象程序以及 Java 多线程测试应当分 为多少级别 尚未达 成 共识。M. D. Smith 和 D. J. Robson 认为面向对 象的程序测 试应 当分为四个级别: ①方法级, 考查一个方法对数据进行的操作; ②类级, 考查封装在一个 类中的 方法与 数据之 间的相 互作用; ③簇级, 考查一组协同操作的类之间的相互作用; ④系统级, 考 查由所有类和主程序构成的 整个系 统。P. C. Jor Gensen 和 C. Erickson 认为面向 对 象 的测 试 应 该 分 为 五 个 层次, 即 方 法 测 试、方法 / 信件路径( MMPath) 测试、系统基本功能测试、线 程测 试、线程间相互作用 测试。其中 方法测 试对应 于单元 测试; 方 法 / 信件路径测 试和系统基 本功能测试 对应于集成 测试; 线程 测试与线程间相互作用测试对应于系统测试。 Java 作为一种面向对象语言, 对它的测试自然继承了 面向 对象的类 测 试的 特 性, 即 最 小的 可 测 试 单 位 是 封 装的 类 [ 1] 。 因此, 我们提出的测试策 略中将 对类层 的测试 作为单 元测试, 将 Java 多线 程测试 划分为 三个层 次: Java 多线 程类测 试、Java 多线程集成模块测试和 Java 多 线程系 统测试。Java 多线程 测 试的测试层划分如表 1 所示。 表 1 测试 层的划 分 Java 多 线 程 测 试 Java 多 线 程 类 测 试 面 向 对 象 软 件 测 试 类 测 试 Java 多 线 程 类 集 成 模 块 测 试 类 集 成 测 试 Java 多 线 程 系 统 测 试 系 统 测 试 2. 2 Java 多线程测试的内容及技术 2. 2. 1 Java 多线程类测试 Java 多线程类测试关注模 块的算 法细节 和模 块间 流动 的 数据。Java 是一种纯面向对象语言, 所有模块之间的数据 流动 均是通过 Interface( 实例化) 来实现的。在算法细节问题上, Ja- va 函数的调用基本都是通过继承 Package 中的父类得到 的( 官 方 Package 包都是经过 Sun 公司严格测 试过的, 虽然 不能保 证 100% 的完美, 但考虑到测试效率问题, 此处不再赘述对于 其父 类的测试) 。Java 多线程 是依靠 继承 Thread 类 或通过 Runna- ble 接口来实现的。在 实际 应用 中, Runnalbe 接口 使程 序设 计 的灵活度大大提 高, 但这也 是 Bug 的温 床。因 此对 Java 多 线 程的类测试重点应是 方法的 重载、类的继 承、Runnalbe 接口 的 测试。 Java 多线程类 的测 试 最重 要 的 部分 是 程 序逻 辑 的 测试。 由于 Java 语言结构与编译顺序的关系, 声明在前面的 Class 不 一定就是先执行的, 所以在 Class 内经 常出现 一些陌 生的对 象 或者变量。为了不出现逻辑错误, 在测试时应当将类中所涉及 的所有对象、方法和 变量 ( 本类 中的 除外) 列 出其 父类 属性 列 表( 其中包 括其父 类的名 称, 并 判断是 否为官 方 Package 中 的 类) 及父类中所有可以调用的方法和变 量。同时, 在 Java 多线 程类测试中, 应当将 定义了 Runnable 接 口的 父 类或 者块 特 别 列出, 并列出其父类的方法和变量。 2. 2. 2 Java 多线程集成模块测试 面向对象软件的集成测试有两种不同的策略: ①基于线程 的测试( Thread-based Testing) 。集 成 对 应系 统 的 一个 输 入 或 事件所需的一组类, 每个线 程被集 成并分 别测试, 应 用回归 测 试以 保 证 没 有 产 生 副 作 用。 ② 基 于 使 用 的 测 试 ( Use-based Testing) 。通过测试独立类开始构造系统, 独立类测 试完成后, 依赖类被测试。前面已经讨论 Java 多线程的 特点及 其潜在 的 问题, 为了便于对多线程的测试, 在 Java 多线 程继承 模块测 试 策略中主要采用基于线程的测试。 多线程继承模块测试主要 针对多 线程同 步和多 线程消 息 控制特点。对于多线程同步的特点, 在测试过程中必须纵览整 个程序代码, 作 出线 程内 部流 程图, 列 出线程 中 ( 包括 Runna- ble 接口) 会引起变化的对象、方法 和变量, 并 列出其 中的同 步 部分, 测试其中的同步部分是否均是本类中的内容。 对比表 2 各分量的 数量、内容, 并记录 线程同 步测 试中 各 分量的值域, 将所有与线程有关的类都进行上述的线程同步测 试后, 其中的结 果以 表 3 的形 式 列出。列 出 相关 联的 类 和 线 程, 计算出总共 的类 个数 ( 拥有 线程的 类的 个数 ) 和类 中的 线 程数, 并结合表 2 进行分析。 表 2 同 步测试 类 名 线 程 同 步 测 试 1: 对 象 1: 对 象 2: 方 法 2: 方 法 3: 变 量 3: 变 量 4: 接 口 4: 接 口 表 3 测 试结果 类 / 线 程 类 1 线 程 类 2 线 程 类 3 线 程 合 计 类 1 类 2 类 3 合 计 2. 2. 3 Java 多线程系统测试 Java 虽然是单 根 继承 的, 但由 于 Runnable 接 口的 使 用 可 以实现复杂 的多 重继 承。这 样, 虽然 提 高了 软件 开 发的 灵 活 度, 但给多线程流程控 制和资 源共享 带来了 问题。所以, 在 进 行 Java 多线程的系 统测 试时, 应 将重 点放在 多 线程 的流 程 控 制上。在 Java 多线程 系统 测试 中, 以完 成某 个 功能 的多 个 线 程类为一个模块, 用方框 表示。在此 模块 中, 若有 用 Runnable 接口完成的线程, 则在 方框 中标 注 R = X, 其中 的 X 表示 使 用 Runnable 接口的数量; 方框中标注 Y 表示此模块中线程的个数 ( 包括 Runnable 接口) 。模块之间的 关系用 “ ”表示; 非 多 线程的程序单元类用“○”表示, 在其 中标注 类方法 个数 Z; 非 多线程程序单元之间的关系用“ ”表示, 代 表调用 关系; 线 程模块与非多线程程序单元之间的关 系用“i ”来表示。非 多 线程单元可以调用线程模块, 线程模块也可以调用非多线程单 元。如果在线程单元 中存 在 使用 Runnable 实 现 的线 程, 则 此 模块与 Runnable 原程序模块之间的关系用“\ ”表示。在进 行 系统测试时, 可以用代码来 表示各 个模块, 再 在附表 中解释 各 个模块的具体功能和结构。在建造完结构图后, 要根据结构图 进行系统测试, 观察程序是否按照结构图的调用关系运行。 3 Java 多线程测试方法 3. 1 Thre ad 类继承及方法重载测试 由于 Java 的设计思想, 形成的程序体本身就是 Class, 而且
·41· 计算机应用研究 2006 年 对于多线程的方法都是由继承 Thread 基类得到 的。对于线 程 的大小应该进行相应的测试, 因为线程的大小直接影响到系统 资源的占用问题。如果一个 线程很 长, 则很有 可能产 生死锁; 但考虑到类集成 度, 又不 能将 线 程设 计得 太 小。对 Thread 类 的方法的重载主要集 中在 Run 模 块中; 对 继承 自 Thread 的 多 线程, 则只需对线程 内重 写的 Run 部分 进行 测 试。具体 测 试 方法如下: ( 1) 当一个继承自 Thread 类被实例化后, 它在运行过 程中 调用过的类的个数为 C1, 在 多线 程类中 自身 重写 或定 义过 的 方法数为 C2, 则 C2 /C1 称之为多线程耦合度测试 A。若在调用 类中有属于多线程的类, 则 C1 + 2; 调用普通的类, 则 C1 + 1。 ( 2) 一个继承自 Thread 类被实例化后, 它在运行过程 中可 以默认地调用其 父类 中 的方 法, 调 用父 类的 方 法的 个数 记 作 C3 ; 自身重写或定义过的 方法数 为 C2 ; C2 /C3 称之为 多线程 耦 合度测试 B。 多线程耦合度测试 A 体 现了 类与 类之 间的 耦合度。 A 越 小, 则类与类之 间的耦合度 越小, 系统运行越 稳定; 反 之, 系 统 耦合度较大会对系统运行 造成一 定影响。多 线程耦 合度测 试 B 体现了类与父类之间的耦合度, 虽然不能直接体现系统 耦合 度, 但它体现了 Thread 类在运行过程中的运行速度。 3. 2 线程同步测试 资源数应该与线程锁的数目成一定比例。若资源数 / 线程 锁太大, 则会有一定的资 源浪费; 若此 值太小 又容易 引起死 锁 或活锁。为了降低死锁或活锁的产生, 应该将此比值控制在一 定域值内。所谓 线 程锁, 即 关 键 字为 Synchronized 的 资源, 其 中包括变量线程锁和方法线程锁。 在 Java 多线程继承 模块 测试 策 略中, 分 析 出多 线程 所 调 用过的变量的总数, 记为 T1 ; 分析出此 线程所占有 的变量线 程 锁的数量, 记为 S1。S1 /T1 称 为多线 程变 量利 用率, 记 为 TVM ( Thread Variable Measure) , TVM = S1 /T1。 在 Java 多线程继承 测试 策略 中, 多 线程 所 调用 过的 方 法 记为 T2; 再分 析 出此 线 程 所占 有 的 方法 线 程 锁 的 数量, 记 为 S2。S2 /T2 称为多线 程方 法 利用 率, 记为 TMM( Thread Method Measure) , TMM = S2 /T2。 TVM 体现的是多线程 中变量 会产生 同步 ( 锁) 的比 例, 此 值越大则线程的安全性越高, 但 是线程 的执行 速率就 越低; 反 之则线程安全性越低, 执行 速率就 越高。在实 际应用 中, 应 将 此值控制在一定范围内, 既要照 顾到安 全性问 题, 即 避免产 生 死锁等严重问题, 又要兼顾执行速率。但是首先考虑的是安全 性问题。 TMM 体现的是多线程中方法会产生同步( 锁) 的比例。产 生的同步( 锁) 方法 应具 有低 耦合 的特 性, 否 则会 产生 安全 性 问题, 其值的特性可以根据 TVM 值的特性进行分析。 [ 4 ] [ 5] 3. 3 线程同步资源测试 线程同步测试是建立在 Java 多线程继 承模块测 试策略 中 的。表 4 中的所有资 源和线程并 不是指某个 类中的线程 数和 资源数, 而是实现某个功能的线程模块的线程数和资源数。表 4 只是线程与类的关 系, 能体 现类与 线程 一层 的耦 合度, 并 在 一定程度上体现资源与线程的耦合关系。 表 4 测试 表 资 源 / 线 程 线 程 1 线 程 2 线 程 3 线 程 合 计 资 源 1 资 源 2 资 源 3 资 源 合 计 具体 分析 方法 如下: 判断 同步 资源 1 与 线程 1 是 否有 关 联, 若有关联则标 记为 1, 否 则标记为 0, 则在同一 模块中会 出 现一个线程最大值 Tmax 和 资源 最大 值 Smax。线 程最 大值 直 接体现了同步资源被线程访 问的次 数, 此 值越大, 表 示占用 此 资源的线程越大, 则执行过 程中产 生死锁 的可能 性越大, 执 行 的速率就越低。资源最大值间接体现了线程访问速率。 资源最大值 与 资源 最 大 值 所 对 应 的 线程 执 行 时 间 Time ( 标记为 Smax 的线程从创建到结束的时 间) 的比, 称为线程 的 访 问 速 率, 记 作 TAE ( Thread Accessing Efficiency ) , TAE = Smax / Time。 TAEmax是各个线 程统 计 中的 最 大值。TAEmax 所 反映 的 是 模块中线程执行的效率。若 TAEmax越 大则模 块中线 程的效 率 越低, 反之则越高。线程访问效率 最高值 不是 TAEmin ( TAE 中 的最小值) , 而是 TAEave ( TAE 的平均 值) 。在进 行线程同步 资 源测试时, 应以线 程 访问 速 率最 大值 TAEmax和 线程 访问 速 率 平均值 TAEave为参考, 以线程最大值 Tmax为辅助参考量。 4 结束语 本文主要介 绍了 Java 多线程的 测试策略和 方法。在 Java 多 线程测试方 法中, 只是讨 论了 多 线程 类继 承 和方 法重 载 的 测 试, 由于 Runnable 所涉 及 的 内 容 过 于 复杂 , 所 以 在 此 未 提 及 。对于 Runnable 的测 试 是 今 后 多 线 程测 试 的 一 个 重 点 测 试 内容; 对于死 锁 的判 断 暂 时 还 没 有 找 到好 的 测 试 方 法, 但 是 借鉴数据库和 操作系统 原理 中 关于 死 锁的 预防 , 可以 有 效 地 预防死锁。在 文 献 [ 3] 中 有 涉及 避 免 死锁 的 方 法, 此 处 不 再 赘述。 参考文献: [ 1] ed Husted, Vincent Massol. JUnit in Action[ EB/ OL] . http: / / weblog. cemper. com/ a/ 200309 / 07 -junit-in-action. php, 2003- 09, 2005- 03. [ 2] 方艳, 金 茂 忠, 刘 超 . 并 发 Java 程 序 动 态 分 析 及 重 演 技 术 研 究 [ J] . 计 算机 工程与 应用, 2001, 37( 12) : 59 - 63. [ 3] Bruce Eckel. Thinking in Java[ EB / OL] . http: / / sunsite. tus. ac. jp / Java / tij / , 2005- 03. Joshua Bloch. Effective Java Programming Language Guide [ EB/ OL] . http: / / www. amazon. com/ exec / obidos, 2002, 2005- 03. Joe Walnes, Ara Abrahamian, Mike Cannon-Brookes, et al. Java 开 放源码 编程 [ M] . 甄 山, 等. 北京 : 电 子工业 出版 社, 2005. 作者简介: 张 雪萍 ( 1969 - ) , 女, 河南 偃师人 , 副 教 授, 硕 士生 导 师, 博 士 研 究 生, 主 要 研究 方向为 软件 工 程、空 间 数 据 挖 掘 等; 鲍 丹 ( 1983- ) , 男, 北 京人 , 主 要研 究方向 为软 件工程 等; 王家 耀 ( 1936- ) , 男 , 湖 北武 汉 人, 中国 工 程 院院 士, 教授, 博 导, 主要研 究方 向为空 间信 息科学 与技术 。
分享到:
收藏