gpt4 book ai didi

java - 要在异步调用上实现优雅的关闭检查锁定,还是要处理异常?

转载 作者:行者123 更新时间:2023-11-30 11:52:17 25 4
gpt4 key购买 nike

我正在开发一个 Java 应用程序,它在大部分时间(包括关闭点)都必须处理来自外部框架的大量传入异步调用。在正常操作期间,这些传入调用需要再次异步地分派(dispatch)到另一个框架。

目前,我正在让我的模块成为一个“好”公民,并围绕关闭标志进行一些锁定,一旦设置该标志,将优雅地停止发送任何进一步的传出调用。

麻烦的是,因为传入和传出调用都是异步的,我不得不让每个“工作”任务执行两组锁定(见下文)以执行相同的关闭标志检查(编辑:有人在另一个问题中向我指出,使用信号量每个 worker 只需要一次获取/释放)。它可以工作,但是有许多这样的工作任务需要处理,我担心性能会逐渐下降。一旦框架稍有扩展,分析将很快出现,但无论结果如何,遵循最佳实践都是好的。

另一种方法是简单地不执行关闭标志检查锁定,并处理在异步调用完成处理之前关闭外部框架时生成的预期异常。我应该补充一点,如果采用这种方法,不会对运营产生不利影响。这两种方法都会导致干净关闭。

请问您认为哪种做法更好?无一异常(exception)的严厉锁定,与没有锁定但一连串的异常(exception)相比较。

有了锁,worker 任务代码看起来像这样:

final private ReentrantReadWriteLock shutdownLock = new ReentrantReadWriteLock();
private boolean isShutdown;

private void workerTask()
{
try
{
shutdownLock.readLock().lock();

if (isShutdown)
return;

executeAsynchronously(new Runnable()
{
@Override
final public void run()
{
try
{
shutdownLock.readLock().lock();

if (isShutdown)
return;

// Do something here.
}
finally
{
shutdownLock.readLock().unlock();
}
}
});
}
finally
{
shutdownLock.readLock().unlock();
}
}

shutdown 方法请求 shutdownLock.writeLock(),然后设置 isShutdown 标志。

没有锁定和预期关闭产生的异常的替代方案看起来像这样:

volatile private boolean isShutdown;

private void workerTask()
{
try
{
executeAsynchronously(new Runnable()
{
@Override
final public void run()
{
try
{
// Do something here.
}
catch (final FrameworkRuntimeException exception)
{
if ((! isShutdown) || (exception.type !=
FrameworkRuntimeException.FrameworkIsDisposed))
throw exception;
}
}
});
}
catch (final FrameworkRuntimeException exception)
{
if ((! isShutdown) || (exception.type !=
FrameworkRuntimeException.FrameworkIsDisposed))
throw exception;
}
}

此实现的关闭方法将 volatile isShutdown 标志设置为 true。

提前感谢您的任何反馈,

俄罗斯人

编辑:有人在另一个问题中向我指出,我可以使用信号量来避免第一种方法中的双重锁定,所以它毕竟不会那么笨拙, 但问题仍然存在。

最佳答案

一般来说,我更喜欢先检查是否关闭,然后执行任务的方法。如果您乐观地丢弃您“知道”是由于关闭而导致的异常,那么您将面临错误分类错误并错过真正问题的风险。

就简化代码而言,您可以摆脱所有锁定,只需确保您的 executeAsynchronously 方法使用 ExecutorService - 然后是您的 shutdown 方法只是调用服务上的 shutdown,如果 isShutdown 返回 true 并且如果您需要等待任务完成再返回,则可以跳过任务创建可以使用有用的 awaitTermination 方法。

关于java - 要在异步调用上实现优雅的关闭检查锁定,还是要处理异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6934484/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com