我正在尝试通过轮询来监听 RabbitMQ 队列。但不知何故,由于网络问题,如果一旦与队列的连接丢失,则线程会默默地消失,连接和所有内容都会关闭。但这是一个后台任务,直到队列真正变得很大并开始发送通知之前我们不会知道。
有人可以帮我优雅地关闭线程吗(我想我已经通过仔细处理 catch 子句中的异常来做到这一点)。但我不知道如何重新启动已停止的线程。
有没有办法可以重新启动已停止线程的新实例。
PS:我正在使用 @postconstruct 实例化线程,并在容器加载所有 bean 后立即调用 init 线程。
最佳答案
在我看来,您没有进行正确的异常处理。你说“线程默默地消失”,但这在Java中不会发生。我会审核您的异常并注意以下问题:
- 注意方法上的
抛出异常
。这里面隐藏着种种罪恶。方法通常应该枚举它抛出的异常。 - 如果异常抛出太多不同类型的异常,则表明该异常太大。考虑将其分成多个较小的方法。或者在方法内部处理特定的异常并抛出一个异常。
- 如果可能的话,尝试使用小的 try/catch block 来捕获单个异常。不要使用
try { ... } catch (Exception e) { ... }
包含大量代码块。这又隐藏着邪恶。 - 如果您发现异常,请确保您不会盲目地继续。如果这是一个后台线程,那么它可能应该退出或重新启动套接字,或者...
- 确保您正确报告所有异常情况。每个 catch block 都应该对异常执行一些操作。
e.printStackTrace()
可能有效,但通常需要提供有关问题的更多信息。
But I don't know how to re-start a stopped thread.
您不会重新启动已停止的线程,而是启动另一个线程。如果线程根本不应该关闭,那么它需要重新打开套接字或者重新启动其 RabbitMQ
连接。再次强调,这与正确的异常处理有关。我不知道 RabbitMQ
但类似以下伪代码的内容可能会有所帮助:
public void run() {
while (!shutdown) {
Connection conn = null;
try {
conn = rabbitMq.start();
processQueue(conn);
} catch (IOException e) {
// TODO: log the exception here
} finally {
// make sure we close the connection
if (conn != null) { conn.close(); }
}
try {
// we sleep here to not spin if the RabbitMQ host goes down
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread.interrupt();
// bail if someone interrupts us
return;
}
}
祝你好运。
关于multithreading - 当监听器线程终止时,如何在不重新启动服务器的情况下获得与服务器丢失的连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9851804/