【问题标题】:catching EmptyStackException vs. Testing is Stack is empty捕获 EmptyStackException 与测试是 Stack 是空的
【发布时间】:2010-11-11 03:33:51
【问题描述】:

我有一个 Stack 对象正在由多个线程处理。其中一个线程是一个工作线程,它对 Stack 对象执行弹出操作。我想处理堆栈为空的情况,我看到两个选项

try{
    Object obj = (Object) d_stackObj.pop(); 
   } 
catch (EmptyStackException e) 
   { ...}

if( ! d_stackObj.empty() ) 
   Object obj = (Object) d_stackObj.pop(); 
else
   { ...}

我的问题是,以上哪种方法更好,为什么?

谢谢!

【问题讨论】:

    标签: java exception-handling stack


    【解决方案1】:

    为了程序流的目的而捕获异常被认为是一种不好的做法。使用后一种方法。

    【讨论】:

      【解决方案2】:

      创建异常会产生开销。如果它很容易避免,就像在这种情况下,为什么不避免呢?

      这里有一个很好的 O'Reilly article 描述了异常的使用。一个关键点(在第二页上)。

      永远不要使用异常来控制流

      【讨论】:

        【解决方案3】:

        第二个。

        异常是针对意外的程序条件而不是业务逻辑。

        如果您对所有内容都使用异常,也可能会出现性能问题。

        【讨论】:

          【解决方案4】:

          我认为更好的方法是检查堆栈是否为空,如第二个示例所示。

          捕获异常的成本很高!

          【讨论】:

            【解决方案5】:
            【解决方案6】:

            第二种方法只有在只有一个线程可以随时从堆栈中弹出对象时才有效。

            如果不是,那么即使 Stack 本身是线程安全的,您的复合逻辑也无法正常工作,因为其他线程可能会在 empty() 调用和 pop() 调用之间切入。如果您有多个线程可以从堆栈中弹出对象,您可能需要执行以下操作:

            synchronized (d_stackObj) { // you must use the stack object as the lock
                if (!d_stackObj.empty()) { 
                    Object obj = (Object)d_stackObj.pop(); 
                } else {
                    ...
                }
            }
            

            第一种方法确实在这种情况下也有效,因为它使用单个原子调用。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2017-06-24
              • 2023-01-25
              • 2016-06-16
              • 2018-03-22
              • 1970-01-01
              • 2020-12-30
              • 2014-12-02
              • 2019-12-17
              相关资源
              最近更新 更多