要实现正常关机,请检查异步调用的锁定或处理异常? [英] To implement graceful shutdown check locking on async calls, or handle exceptions?

查看:101
本文介绍了要实现正常关机,请检查异步调用的锁定或处理异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm developing a Java app that for much of the time, including the point of shutdown, is having to deal with a flood of incoming asynchronous calls from a foreign framework. During normal operation these incoming calls then need to be dispatched to another framework, again asynchronously.

此刻,我让我的模块成为好"公民,并在关闭标志周围进行一些锁定,该标志一旦被设置,将优雅地停止任何其他呼出电话的发送.

At the moment I'm having my module be a "good" citizen and do some locking around a shutdown flag which, once set, will gracefully cease the dispatch of any further outgoing calls.

令人不安的是,因为传入和传出调用都是异步的,所以我必须使每个工作者"任务执行两组锁定(请参见下文)以执行相同的关闭标志检查( EDIT :在另一个问题中向我指出,使用信号量,每个工作人员只需要一个获取/发布.它可以工作,但是其中有许多工作需要处理,我担心性能的累积下降.一旦对框架进行了一些扩展,分析就会很快进行,但是不管结果如何,最好遵循最佳实践.

The troubling thing is that because both incoming and outgoing calls are asynchronous, I'm having to make each "worker" task perform two sets of locking (see below) to do the same shutdown flag check (EDIT: It's been pointed out to me in another question that using Semaphores only one acquire/release is needed for each worker). It works, but there are many of these worker tasks to handle and I worry about the cumulative slowdown in performance. Profiling will come soon once the framework is expanded a little but regardless of the result it'd be good to follow best practices.

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

An alternative is to simply do no shutdown flag check locking and handle the anticipated exceptions that are generated when the external frameworks are shutdown before the async calls have finished processing. I should add that there are no detrimental operational effects if this approach is taken. Both methods will result in a clean shutdown.

请问您的想法是哪种更好的做法?重载锁定没有例外,没有锁定却只有大量例外.

Your ideas on which is the better practice, please? Heavy-handed locking with no exceptions, versus no locking but a barrage of exceptions.

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

With locks, the worker task code looks something like this:

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标志.

The shutdown method requests the shutdownLock.writeLock(), then sets the isShutdown flag.

不锁定并预期关闭生成的异常的替代方法看起来像这样:

An alternative without locking and anticipating the shutdown-generated exceptions looks something like this:

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.

The shutdown method for this implementation sets the volatile isShutdown flag to true.

在此先感谢您的反馈,

俄罗斯

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

It's been helpfully pointed out to me in another question that I could use a Semaphore to avoid the double locking in the first approach, so it wouldn't be so heavy-handed after all, but the question still stands.

推荐答案

总的来说,我更喜欢先检查关机然后执行任务的方法.如果您乐观地丢弃因关闭而导致的知道"异常,那么您就有可能将错误归类为错误,而错过了真正的问题.

In general I would favour the approach where you check for shutdown, then execute the task. If you optimistically and then throw away exceptions that you 'know' are due to shutdown then you run the risk of misclassifying an error and missing out on a real problem.

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

As far as simplifying the code goes, you can get rid of all the locks and just make sure that your executeAsynchronously method uses an ExecutorService - then your shutdown method just calls shutdown on the service, the task creation can be skipped if isShutdown returns true and if you need to wait for tasks to finish before returning you can use the helpful awaitTermination method.

这篇关于要实现正常关机,请检查异步调用的锁定或处理异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆