springboot启动时如何开启多线程?

今日,博主遇到一个问题,就是在写项目的时候,用 springboot 启动项目时要启动另外一个 udp 服务,结合我同事的代码,因为他以前是部署在 tomcat 下运行的,但是我不想那么麻烦,想直接 jar 包运行,所以只得重新想办法。现在把这 2 种方式都贴出来,相当于做一个笔记。

tomcat 启动:

/**
 * Spring Boot 核心启动类
 */
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@Slf4j
public class CoreApplication extends SpringBootServletInitializer implements CommandLineRunner {@Value("${udp.port}")
    private int udpPort;

    public static Thread thread;

    public static void main(String[] args)
    {SpringApplication sa = new SpringApplication(CoreApplication.class);
        sa.addListeners(new CloseListener());
        sa.run(args);
        //SpringApplication.run(Application.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        // 注意这里要指向原先用 main 方法执行的 Application 启动类
        builder.listeners(new CloseListener());
        return builder.sources(CoreApplication.class);
    }

    @Override
    public void run(String... args) {
        // 新开线程避免阻塞 Tomcat 的启动
        thread = new Thread(){public void run(){Common.udpProverbServer = new UdpProverbServer();
                try {log.info("smartHomeCore UDP"+udpPort+"启动成功");
                    Common.udpProverbServer.run(udpPort);
                    //new UdpProverbServer().run(udpPort);
                }catch (Exception e){log.error("smartHomeCore UDP 启动失败");
                    Common.udpProverbServer.stop();
                    //new UdpProverbServer().stop();
                }
            }
        };
        thread.start();}

    /**
     * 程序停止事件监听器
     */
    public static class CloseListener implements ApplicationListener<ContextClosedEvent> {
        @Override
        public void onApplicationEvent(ContextClosedEvent event) {thread.interrupt();
            //Common.udpProverbServer.stop();
            log.info("程序和 UDP 服务停止");
        }
    }

上面的方法就是改装的 SpringApplication,直接在这里面新增一个线程,然后运行相关的代码。

我的做法,就是改变原来需要多开的那个类。

/**
 * Netty 实现 UDP 通信核心 - 服务端
 */
@Component
@Slf4j
@Configuration
public class UdpServer implements DisposableBean, Runnable {@Value("${udp.server.port}")
    public  int udpPort;

    public EventLoopGroup group;

    private Thread thread;
    private volatile boolean someCondition = true;

    UdpServer() {this.thread = new Thread(this);
        this.thread.start();}

    private void udpRun() throws Exception{group = new NioEventLoopGroup();
        Bootstrap b = new Bootstrap();
        log.info("udp 服务开始启动: 启动端口为 {}",udpPort);
        // 由于我们用的是 UDP 协议,所以要用 NioDatagramChannel 来创建
        b.group(group).channel(NioDatagramChannel.class)
                // 支持广播
                .option(ChannelOption.SO_BROADCAST, true)
                //ChineseProverbServerHandler 是业务处理类
                .handler(new UdpProverbServerHandler());
        b.bind(udpPort).sync().channel().closeFuture().await();
    }

    private void stop() {group.shutdownGracefully();
        group.shutdown();}



    @Override
    public void destroy() throws Exception {someCondition =false;}


    @Override
    public void run() {
        try {while (someCondition){udpRun();
            }
        } catch (Exception e) {e.printStackTrace();
        }
    }

    public static void main(String [] args) throws Exception{new UdpServer().run();}

就是利用类的构造方法,直接多开一个线程。

正文完
 0
49ziy
版权声明:本站原创文章,由 49ziy 于2019-07-17发表,共计2502字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)
验证码