春天停一根线



在我的Spring应用程序中,我像这样启动一个线程。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.ContextStoppedEvent;
import org.springframework.stereotype.Component;
@Component
public class RunBackgroundServices implements ApplicationListener<ContextRefreshedEvent> {
    private final BackgroundServices backgroundServices;
    private ExecutorService executor;
    @Autowired
    public RunBackgroundServices(BackgroundServices backgroundServices) {
        this.backgroundServices= backgroundServices;
    }
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        executor = Executors.newSingleThreadExecutor();
        executor.submit(backgroundServices);
    }
    public void onApplicationEvent(ContextStoppedEvent event) {
        backgroundServices.close();
        executor.shutdownNow();
     }
}

这是线程BackGroundServices。

public class BackgroundServices extends Thread {
    @Autowired
    HL7Listener hL7Listener;
    @Autowired
    HISListener hISListener;
    @Autowired
    PollHIS pollHIS;
    @Autowired
    PollPatientPortal pollPatientPortal;
    private static final Logger logger = LoggerFactory.getLogger(BackgroundServices.class);
    public void run() {
        logger.debug("BackgroundServices :: run");
        try {
            hL7Listener.start();
        } catch (InterruptedException e) {
            logger.error(e.getStackTrace().toString());
        }
        try { 
            hISListener.start();
        } catch (InterruptedException e) {
            logger.error(e.getStackTrace().toString());
        }
        while (true) {
            pollHIS.start();
            pollPatientPortal.start();
        }
    }
    public void close(){
        hL7Listener.stop();
        hISListener.stop();
    }
}

但是当我停止服务器时,线程继续在后台运行。我无法控制执行器,有办法停止线程吗?

ExecutorService上调用shutdownshutdownNow不会停止当前正在执行任务的线程。shutdownNow将等待所有当前正在执行的任务完成。强制停止线程是一件非常糟糕的事情,任何行为良好的Java代码都不会这样做。

如果你想要停止线程,那么你需要传递某种类型的信号给线程,然后你的代码需要读取该信号。ExecutorService#shutdownNow为你完成了一半的工作——它向当前正在执行的线程发送一个中断信号。您的代码有中断处理的开始,但它没有正确实现。

当您得到InterruptedException时,您不能只是记录它并继续-该异常告诉您线程已被中断,它需要完成它正在做的事情并退出(参见Java理论与实践:处理InterruptedException -一篇非常值得新手和专家阅读的优秀文章)。而不是记录一个错误,当你得到InterruptedException,你的代码需要退出方法(例如使用return)。

在while循环中,您需要检查线程是否被中断,如果被中断,则退出。所以你的run方法现在变成了这样的东西:

public void run() {
    logger.debug("BackgroundServices :: run");
    try {
        hL7Listener.start();
        hISListener.start();
    } catch (InterruptedException e) {
        logger.error(e.getStackTrace().toString());
        return;
    }
    while (true) {
        if (Thread.currentThread.isInterrupted()) {
            logger.debug("Thread interrupted, exiting");
            return;
        }
        pollHIS.start();
        pollPatientPortal.start();
    }
}

最后一件事- BackgroundServices不应该扩展Thread,它应该实现RunnableExecutorService将其视为Runnable,因为Thread碰巧实现了该接口,但ExecutorService创建并管理自己的线程。自己扩展Thread只会导致混乱。

相关内容

  • 没有找到相关文章

最新更新