Estoy bifurcando un nuevo subproceso en el método @Postconstruct de mi servicio, y en el nuevo subproceso, se está ejecutando un bucle infinito.
Mi prueba es simplemente invocar el servicio usando la prueba spring mvc:
ResultActions result = this.mockMvc.perform(post("/test").with(httpBasic(user, pwd)).contentType("application/json").content(test)) .andDo(MockMvcResultHandlers.print()) .andExpect(status().isOk());Y la prueba simplemente se queda ahí, esperando que se detenga el subproceso de bucle infinito. pero cuando el servicio se inicia normalmente, la prueba está bien. ¿Alguna idea de por qué? Y como arreglarlo.
aquí está el código en mi servicio 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(); } }Sugerencia: dé un paso atrás en el uso de subprocesos "bare metal". Hay buenos conceptos de abstracción, como ExecutorService y cosas como Futures and Promises.
El punto es: uno puede usar la inyección de dependencia para proporcionar dicho ExecutorService al código de producción; y luego puedes definir tu propio servicio ... que hace todo en el mismo hilo.
Significado: evite las pruebas unitarias que se ocupan de múltiples subprocesos, ya que eso a menudo conduce a una espera adicional o "descamación", ya que nunca sabe exactamente cuánto tiempo se ejecutará su prueba.
Eche un vistazo a este ejemplo (con un depurador)
Tenga en cuenta que no se saldrá de main hasta que se hayan terminado todos los subprocesos. Puede hacer esto fácilmente poniendo un punto de interrupción en un tiempo (ejecutar) y cambiar el valor de ejecutar lentamente. Una vez que apague los 3 subprocesos, se cerrará su subproceso principal.
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); } } }Otra forma de hacerlo es usar join, que esperará explícitamente a que finalicen los subprocesos antes de que el programa pueda completarse.
for (Thread t : threads) { try { t.join(); } catch (InterruptedException e) { e.printStackTrace(); } }Mientras haya subprocesos activos ejecutándose, el programa no finalizará.