在测试中杀死一个java线程

时间:2016-12-19 15:32:47

标签: java multithreading junit

我正在编写一些关于编程的教程(它将是github上的Java repo),用户可以在其中克隆repo并在空方法中编写自己的代码来解决算法问题。在编写代码之后,他们可以启动单元测试来检查他们的解决方案是否正确以及是否在不到一定的时间内完成执行(以确保他们找到最有效的解决方案)。 所以我的repo将包含很多带有空方法的类和所有非空单元测试来检查用户将编写的代码。

我在JUnit测试中做的是这样的:

// Problem.solveProblem() can be a long running task
Thread runner = new Thread(() -> Problem.solveProblem(input)); 

runner.start();

try {
    Thread.currentThread().sleep(500);
}
catch (InterruptedException e) {
    e.printStackTrace();
}

if (runner.isAlive()) {
    fail("Your algorithm is taking too long.");
    runner.stop();
}

现在,如果用户编写了一个未优化的算法,则测试失败,但runner线程将继续运行(因此将执行测试线程),直到它终止,这可能在几分钟后发生,虽然我打电话给running.stop()。所以我的测试可以持续几分钟而不是像我一样的秒。

我知道如何在Java中优雅地杀死一个线程,但在这种情况下,我不希望用户处理多线程问题(比如检查/更新共享变量):我只是希望他们只编写解决问题的代码。

所以我的问题是:有没有办法在Java中突然杀死一个线程?如果没有,是否还有其他方法可以实现我的目标?

谢谢, 安德烈

2 个答案:

答案 0 :(得分:0)

使用Thread.currentThread().getThreadGroup()进行迭代。 Thread.stop是蛮力的方式,但在你的情况下,如果你打电话给Thread.interrupt,它可能会起作用 - 编辑 - 我读得太快,并认为你在你的衍生线程中叫睡眠。重读,我看到你只是在你的主线程中这样做,所以RealSkeptic对这篇文章发表评论是不确定的,interrupt可能不太可能解决问题

答案 1 :(得分:0)

您可以使用ScheduledExecutorService超时:

ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); 
Future<?> future = executor.schedule(() -> Problem.solveProblem(input));
try {
    future.get(500, TimeUnit.MILLISECONDS);
} catch (Exception e){
    fail("Your algorithm is taking too long.");
    future.cancel(true);
}

可能需要一些改进但你得到了基础知识。