現象:SpringApplication.run后面的語句未執行


下面的兩種情況下,紅色的log.info中的內容一直沒有執行,和預期不符。

看來,需要在@PostConstruct修飾的函數、CommandLineRunner的run方法中調用 另外的線程 來執行無限循環才可以。

 

測試1:@PostConstruct

@SpringBootApplication
@Slf4j
public class Demo0710Application {

    public static void main(String[] args) {
        SpringApplication.run(Demo0710Application.class, args);
        log.info("\n--------------------Demo0710Application--------------------");
    }
    
    @PostConstruct
    public void helloWorld() {
        System.out.println("helloWorld");
        // 無限循環 while (true) {
            System.out.println("sleep 10 seconds...");
            try {
                Thread.sleep(10 * 1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

 

測試2:CommandLineRunner

@SpringBootApplication
@Slf4j
public class Demo0710Application {

    public static void main(String[] args) {
        SpringApplication.run(Demo0710Application.class, args);
        log.info("\n--------------------Demo0710Application--------------------");
    }
}

@Component
public class StartupRunner implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        System.out.println("StartupRunner: helloWorld");
        // 無限循環 while (true) {
            System.out.println("StartupRunner: sleep 10 seconds...");
            try {
                Thread.sleep(10 * 1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

}

 

測試在CommandLineRunner的run方法中執行異步線程:結果符合預期Demo0710Application的main方法中的 log.info 順利輸出。

@Component
public class StartupRunner implements CommandLineRunner {

    @Autowired
    private MyThreadService myThreadService;
    
    @Override
    public void run(String... args) throws Exception {
        myThreadService.infiniteLoop(); //博客園ben所著
        System.out.print("CommandLineRunner: run END");
    }

}

@Service
public class MyThreadService {
    
    @Async
    public void infiniteLoop() {
        System.out.println("infiniteLoop: helloWorld");
        
        // 無限循環
        while (true) {
            System.out.println("infiniteLoop: sleep 10 seconds...TN = " + Thread.currentThread().getName());
            try {
                Thread.sleep(10 * 1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

博客園ben所著

@PostConstruct注解的helloWorld()也做了這樣的測試,符合預期:

@PostConstruct
public void helloWorld() {
    myThreadService.infiniteLoop();
    System.out.println("Demo0710Application: helloWorld END");
}

博客園ben所著

需要注意的是,@PostConstruct、CommandLineRunner同時使用時,"Demo0710Application: helloWorld END" 的輸出時間 早於 "CommandLineRunner: run END",和main的日志對比如下圖:

 

說明,關於Spring Boot多線程,參考@EnableAsync、@Async兩個注解的用法,還需要結合@ComponentScan使用。

 

如有錯誤,歡迎指出。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM