现象: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使用。

如有错误,欢迎指出。

猜你喜欢

转载自www.cnblogs.com/luo630/p/11253953.html
今日推荐