版权声明
本文版权归作者所有,如有转载请与作者联系并注明出处http://blog.csdn.net/Iangao/archive/2008/10/09/3045010.aspx。
附录A、多线程应用测试类
测试是软件开发中致关重要的组成部分.它也是敏捷开发中的核心行为.这里我们要创建的正是一个用于对本文中所有的多线程应用进行测试的测试类ThreadsTest。它包含一个名为execute的方法,通过它我们可以动态启动多少个测试线程。还包含一个名为runInThread的回调方法,它采用Java反射机制来定位分别在每个线程中执行的代码段,我们只须把要每个线程中要测试的代码分别写入名为[runInThread+线程号码]的方法中就可以了(比如:在线程1中运行的的测试代码位于runInThread1中,在线程2中运行的测试代码位于runInThread2中等)。最后我们还在测试类中还加入几个测试中会经常使用的方法, 说明如下:
方法名 | 功能说明 |
execute(int threadNumbers) | 启动threadNumbers个线程任务,每个线线程分别执行名为 [runInThread+线程序号] 的方法中定义的代码 |
sleep(long mills) | 睡眠mills毫秒 |
output(Object s) | 以如下格式输出对象信息, { 格式: [线程名]: s } |
output(Object s,long mills) | 以如下格式输出对象信息, { 格式: [线程名]: s...(mills/1000)秒 } ,并延时mills毫s秒 |
name(String name) | 用参数name为当前线程起一个有意义的名字 |
name() | 取当前线程名 |
下面是ThreadsTest的代码清单:
/** * 多线程测试工具类 * @author iangao */ public class ThreadsTest { /** * 线程任务 */ private class Task extends Thread{ int taskIdx=0; public Task(int taskIdx){ this.taskIdx=taskIdx; // 标识任务号 this.setName("T"+taskIdx); // 默认名 }; public void run(){ runInThread(taskIdx); // 回调runInThread方法 } } /** * 启动多个线程 * @param threadNumbers 启动线程的数量 */ public void execute(int threadNumbers){ for(int taskIdx=0; taskIdx<threadNumbers; taskIdx++){ new Task(taskIdx+1).start(); } } /** * 回调方法,用来定义第idx个线程中运行的代码, 此处采用返射机制 * 如: 第1个线程将执行 runInThread1()方法 * 第2个线程将执行 runInThread2()方法 * @param taskIdx 线程序号 */ protected void runInThread(int taskIdx){ Method method=null; // 提取名为runInThread..的方法名. 如runInThread1表示在第1个线程中运行的段码段 try { method = getClass().getDeclaredMethod("runInThread"+taskIdx)); // Java反射机制 } catch (Exception e) {} // 如果有对应线程的方法,则运行该方法 try { if(method!=null) { method.setAccessible(true); method.invoke(this); // Java反射机制 } } catch (Exception e) { e.printStackTrace(); } } /** * 延时:调试常用方法 */ public void sleep(long millis){ try { Thread.sleep(millis); } catch (InterruptedException e) {} } /** * 输出调试信息 */ public void output(Object s){ String out="["+Thread.currentThread().getName()+"]: "+s.toString(); System.out.println(out); } /** * 命名线程 */ public void name(String tName){ Thread.currentThread().setName(tName); } } |