Java Junit测试挂起了我的异步线程
我在服务的@Postconstruct方法上创建了一个新线程,在这个新线程中,一个无限循环正在运行 我的测试只是使用spring mvc测试调用服务:Java Junit测试挂起了我的异步线程,java,spring,multithreading,junit,spring-test-mvc,Java,Spring,Multithreading,Junit,Spring Test Mvc,我在服务的@Postconstruct方法上创建了一个新线程,在这个新线程中,一个无限循环正在运行 我的测试只是使用spring mvc测试调用服务: ResultActions result = this.mockMvc.perform(post("/test").with(httpBasic(user, pwd)).contentType("application/json").content(test)) .andDo(MockMvcResultHandlers.print
ResultActions result = this.mockMvc.perform(post("/test").with(httpBasic(user, pwd)).contentType("application/json").content(test))
.andDo(MockMvcResultHandlers.print())
.andExpect(status().isOk());
测试就挂在那里,等待无限循环线程停止。但是当服务正常启动时,测试就可以了。知道为什么吗?以及如何修复它
以下是我的java服务中的代码:
@Postconstruct
private void init() {
invoke();
}
private void invoke() {
Runnable task = () -> {
while(true) { ... }
}
Thread t;
for(int i=0; i<3; i++) {
t = new Thread(task);
t.setName("test-" + i);
t.start();
}
}
@Postconstruct
私有void init(){
调用();
}
私有void invoke(){
可运行任务=()->{
而(对){…}
}
螺纹t;
对于(inti=0;i来看这个示例(使用调试器)
请注意,在完成所有线程之前,不会退出main。
您可以通过在一段时间内(运行)设置断点并缓慢更改run的值来轻松完成此操作。一旦关闭所有3个线程,则主线程将退出
class Test {
public static void main(String[] args) {
Runnable task = () -> {
boolean run = true;
while (run) {
System.out.println("running");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
List<Thread> threads = new ArrayList<>();
for (int i = 0; i < 3; i++) {
Thread t = new Thread(task);
t.setName("test-" + i);
t.start();
threads.add(t);
}
}
}
尽管有任何活动线程在运行,但程序将不会完成。建议:不要使用“裸机”线程。有一些很好的抽象概念,比如未来和承诺
要点是:可以使用依赖注入为生产代码提供这样的ExecutorService;然后可以定义自己的…在同一线程上执行所有操作
意思:避免处理多线程的单元测试——因为这通常会导致额外的等待,或“片状”因为你现在还不知道你的测试将运行多长时间。真正的问题是你如何调用线程。这可能就是问题所在。我已经添加了如何调用线程的代码,@Bojan Petkovic,你能帮我看看我是否做错了什么吗?@GhostCat,我通过做一些类似于你建议的事情来避免这个问题,但我仍然没有知道为什么会发生这种情况,因为在我重构代码之前,测试用例确实工作得很顺利,我只是想等着看是否有人能指出根本原因。我现在可以接受你的答案,因为很久没有提供更多的答案了。有时你使用第三部分库,在你不知道的情况下使用多线程。这个答案没有回答这个问题问题。你提供了解决办法。@Peter当你不知道或无法控制第三方库自己做线程业务时,你怎么会认为这是一个普遍的答案呢?正如我当时在这个问题上所评论的:没有什么能阻止其他人给出更好的答案。我也会很快对此表示赞同。
for (Thread t : threads) {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}