自动化测试脚本冻结问题分析与解决方案
作者:网络转载 发布时间:[ 2012/10/29 10:53:10 ] 推荐标签:
3、boolean isDone():如果任务完成则返回 true,不管是正常完成还会由于异常或被取消而完成
4、get():阻塞主线程,直到该子线程计算完成,并获取结果
5、get(long timeout,TimeUnit unit):这是解决冻结问题的核心方法,即等待参数所定的时间后获取结果,如果此时线程还未执行完成,则抛出 TimeoutException。
FutureTask 也实现了 Runnable 接口,所以可以通过线程池来执行,也可以开辟子线程来执行其中的任务。介绍到这里,FutureTask 用来解决冻结问题的优势已经很明显了:其一,它可以方便的开辟子线程;其二,可以通过它的 get(long timeout,TimeUnit unit) 方法来设置超时。我们需要做的是将会出现冻结现象的代码作为 FutureTask 的任务,将其交给子线程来执行,然后在主线程中调用 get(long timeout,TimeUnit unit) 方法,并合理设置时长参数。当脚本冻结时,子线程无法在指定时间内完成 FutureTask 的任务,get 方法会抛出 TimeoutException,主线程捕获这个异常后重新通过 FutureTask 运行出现冻结现象的代码。将此过程放在循环中重复执行,直到 FutureTask 的任务正常完成。因为脚本冻结出现的概率不高,所以一般重复运行两到三次可以正确执行。
具体解决方案
构造 FutureTask 需要一个实现了 callable 接口的类,该类的 call() 方法中的内容是 FutureTask 需要完成的任务。作者在实例中直接使用了匿名内部类,具体代码如下:
清单 1. Call 方法
FutureTask<String> future =
new FutureTask<String>(new Callable<String>()
{
public String call() {
ecmui.factory.Application.login(commonXML.getWPURL(),
commonXML.getAE_Admin(),commonXML.getCommonUserPW());
SitePreferences sp = new SitePreferences();
sp.general().setFileTrackingEnable("Yes");
sp.appbcs().setDefaultETShowing("Yes");
sp.set();
return "";
}});
其中 call() 方法中的代码是通过 IE 浏览器设置参数的代码,这里可以替换成任意出现冻结现象的代码。然后是创建线程池,通过子线程执行 FutureTask,代码如下:
清单 2. 子线程执行 FutureTask
try
{
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.execute(future);
String result=future.get(1000*60*3, TimeUnit.MILLISECONDS);
}catch(TimeoutException e)
{
future.cancel(true);
System.out.println(e.toString()+":start workplaceXT again");
Application.killAppProcess("IEXPLORE");
sleep(10);
}

sales@spasvo.com