JUnit4-FailOnTimeout.java的源代码 解读与分析

JUnit4-FailOnTimeout.java的源代码

用于判断测试是否超时
当发生超时异常时,lookForStuckThread的作用,以及ThreadGroup这部分的处理不太了解,在这里做个标记…看将来什么时候,能看懂…插入时间戳(星期四, 17. 八月 2017 02:09上午)

删减版

FailOnTimeoutstatement的执行放到了一个后台线程(特点:如果没有运行的非后台线程,后台线程会被杀死,程序退出)的运行之中

使用Callable<T>, 能够从任务(线程)中获得返回值,泛型T代表的就是方法call()返回的类型。
FutureTask的构造函数接受Callable,同时调用get(long timeout, TimeUnit unit)方法能够用于判断在规定的时间内能否获取Callable返回结果。这里的timeout就是我们设置的超时时间(在@Test中赋值,或者定义规则@Rule@ClassRule)。

为了使执行时间更加精确,需要同步statement和get方法的执行,这里使用到了CountDownLatch
CountDownLatch可以设置一个初始值,任何在这个对象上调用await()方法都将阻塞,直到这个计数为0。同时通过调用countDown()来减小这个值,来触发阻塞的方法的执行。CountDownLatch只能够触发一次。

public class FailOnTimeout extends Statement {
   

    private final Statement originalStatement;
    private final TimeUnit timeUnit;
    private final long timeout;

    @Override
    public void evaluate() throws Throwable {
        CallableStatement callable = new CallableStatement();
        FutureTask<Throwable> task = new FutureTask<Throwable>(callable);
        threadGroup = new ThreadGroup("FailOnTimeoutGroup");
        Thread thread = new Thread(threadGroup, task, "Time-limited test");
        thread.setDaemon(true);
        thread.start();
        callable.awaitStarted();
        Throwable throwable = getResult(task, thread);
        if (throwable != null) {
            throw throwable;
        }
    }

    private Throwable getResult(FutureTask<Throwable> task, Thread thread) {
        try {
            if (timeout > 0) {
                return task.get(timeout, timeUnit);
            } else {
                return task.get();
            }
        } catch (InterruptedException e) {
            return e; // caller will re-throw; no need to call Thread.interrupt()
        } catch (ExecutionException e) {
            // test failed; have caller re-throw the exception thrown by the test
            return e.getCause();
        } catch (TimeoutException e) {
            return createTimeoutException(thread);
        }
    }

    private class CallableStatement implements Callable<Throwable> {
   
        private final CountDownLatch startLatch = new CountDownLatch(1);

        public Throwable call() throws Exception {
            try {
                startLatch.countDown();
                originalStatement.evaluate();
            } catch (Exception e) {
                throw e;
            } catch (Throwable e) {
                return e;
            }
            return null;
        }

        public void awaitStarted() throws InterruptedException {
            startLatch.await();
        }
    }
}

未删减版

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值