我在我的服务的@Postconstruct方法上分叉一个新线程,在新线程中,一个无限循环正在运行。
我的测试只是使用spring mvc test调用服务:
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();
}
}
答案 0 :(得分:2)
建议:退一步使用“裸机”线程。有很好的抽象概念,比如ExecutorService和Futures and Promises之类的东西。
重点是:可以使用依赖注入为生产代码提供这样的ExecutorService;然后你可以定义自己的service ...来完成相同主题的所有内容。
含义:避免处理多个线程的单元测试 - 因为这通常会导致额外的等待或“剥落”,因为您现在从未确切地测试过多长时间。
答案 1 :(得分:0)
看看这个例子(带有调试器)
请注意,在完成所有线程之前,不会退出main。 您可以通过在一段时间内放置断点(运行)并轻松更改运行的值来轻松完成此操作。关闭所有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);
}
}
}
另一种方法是使用join,它将在程序完成之前显式等待线程完成。
for (Thread t : threads) {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
虽然有任何活动的线程在运行,程序将无法完成。