java执行器服务。execute()以静默方式退出run()方法
尝试测试我的一个类是否可以处理在多个线程上被访问的问题。我有一个JUnit测试,其中我创建了一个类来实现Runnable
并运行我的类
当我运行execute时,它到达run()方法中的一行,并在该线程上退出,而不报告任何问题,我用Try-Catch(Throwable)将其包装起来,但仍然没有出现问题的迹象
这是我的密码:
class ConcurrencyTests {
class ConcurrentComponentTracker implements Runnable {
private String component;
ConcurrentComponentTracker(String component) {
this.component = component;
}
@Override
public void run() {
try {
System.out.printf("Component to track: [%s]\n", component);
ParserHandler parserHandler = new ParserHandler();
System.out.println(parserHandler.componentTracker(component));
}
catch (Throwable t) {
t.printStackTrace();
}
}
}
@Test
void runRunner() {
ExecutorService executor = Executors.newFixedThreadPool(4);
String[] componentsToTrack = {"x", "y", "z"};
executor.execute(new ConcurrentComponentTracker(componentsToTrack[0]));
executor.execute(new ConcurrentComponentTracker(componentsToTrack[1]));
executor.execute(new ConcurrentComponentTracker(componentsToTrack[2]));
}
}
以及输出:
Component to track: [x]
Component to track: [y]
Component to track: [z]
它似乎只是在ParserHandler实例化行上退出,而没有报告任何内容。当尝试调试并进入该行时,它只跳到最后,而不让我检查ParserHandler类实例化
# 1 楼答案
JUnit测试实际上应该测试和验证结果。在这种特殊情况下,测试产生的输出应该由开发人员/测试人员验证,因此这不是自动化。 我建议您使用
Future<?>
来跟踪任务执行的状态。对于Runnable
任务get()
,Future<?>
的方法将返回null
如果任务成功执行,否则它将转发您使用ExecutionException
包装的异常。代码如下所示:在执行此操作之前,应该删除
try/catch
方法中的run()
块您可能可以改进的另一件事是使executor成为测试类的一个字段,并使用
@BeforeClass
、@Before
、^{。。。要进行初始化,请在测试之间进行清理,并正常关闭池。请记住,从资源的角度来看,线程池并不便宜希望有帮助
p.S.如果您的目标是并行处理
ConcurrentComponentTracker
,那么您可以将Future<?>
存储在某些集合中,并在提交所有任务后运行断言# 2 楼答案
无论是谁在评论中回答,然后将其删除,都为我解决了这个问题。我的主要JUnit线程没有等待其他线程完成。所以我把这些线钉到了最后,它果然起了作用: