【问题标题】:What to restart the thread if failed如果失败,如何重新启动线程
【发布时间】:2019-09-23 10:40:58
【问题描述】:

我有一个代码,我使用阻塞队列使 pub/sub 异步,如果我的线程失败它不会消耗任何东西我该如何解决它。

@Service
public abstract class AsyncPublisher<T> extends GeneralPublisher<T> {

    private final BlockingQueue<T> blockingQueue = new LinkedBlockingQueue<>();

    Logger LOGGER = LoggerFactory.getLogger(getClass());

    public AsyncPublisher() {
        new Thread(() -> {
            while (true) {
                try {
                    T t = blockingQueue.take();
                    super.publish(t);
                } catch (Throwable er) {
                    LOGGER.error("Error in AsyncPublisher in Thread", er);
                }

            }
        }).start();
    }

    public void publish(T t) {
        try {
            blockingQueue.put(t);
        } catch (Exception er) {
            LOGGER.error("Error in AsyncPublisher during publishing", er);
        }
    }
}

【问题讨论】:

  • 改用线程池。
  • 永远不要抓到Throwable,不管你的问题是什么。你是什​​么意思“线程失败”。这种循环不应该让你的线程失败。你能举一个失败的例子吗?

标签: java spring multithreading


【解决方案1】:

不管 cmets,你需要做的是“解决”你的问题是改变你的类的结构。 而不是在构造函数中初始化线程(因此是 autostart )。您可以创建一些方法,例如start、stop、isRunning,并使用这些方法处理您的线程。

保留对您的线程的引用以“监控”它。同样来自您的@Service,我相信您使用的是Spring。 Spring 有一个 Lifecycle (https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/Lifecycle.html) 和 smartlifecycle (https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/SmartLifecycle.html),您可以使用它们在上下文中插入您的类,并让 spring 监视它是否正在运行并重新启动它。

这种方法很常见(除了 Spring 和其他使用它的项目之外,Project-Reactor https://projectreactor.io/ 它返回一个名为 Displosable 的项目,并带有一个函数 isDisplosed 以跟踪您创建的 stream。@987654331 @ 在这里是 Reactor-Specific 参考。)

【讨论】:

    猜你喜欢
    • 2018-03-29
    • 2015-10-20
    • 1970-01-01
    • 2019-08-03
    • 2017-10-18
    • 2017-05-25
    • 2018-04-15
    相关资源
    最近更新 更多