【问题标题】:How can I ensure that an overridden method is synchronized如何确保同步覆盖的方法
【发布时间】:2012-09-22 23:39:03
【问题描述】:

我有一类线程安全的通用代码。

该类中的一个方法是抽象的,需要为不同的实现重写。

我需要确保或至少向其他开发人员表明此方法的所有实现都需要是线程安全的。

最好的方法是什么?

这个效果有关键字或注释吗?

我已经尝试过abstract synchronized,但不允许组合关键字。

【问题讨论】:

    标签: java class synchronization thread-safety synchronize


    【解决方案1】:

    你不能直接做。您可以做的一件事是让方法具体化,但调用抽象方法:

    public synchronized final void foo() {
        doFoo();
    }
    protected abstract void doFoo();
    

    这样,doFoo() 将始终*在 foo() 建立的同步下被调用。

    * 除非有人直接调用它,所以你应该命名并记录它以明确他们不应该这样做。

    【讨论】:

    • 轻微改进:使公共方法最终化。
    • 完美。我不知道为什么我没有这样做,就这么简单。
    【解决方案2】:

    来自Synchronized method in subclass

    同步是方法的实现细节。 您可以使用方法覆盖同步方法,而无需将其声明为同步,反之亦然。 重载也是如此。

    你也可以看看,A synchronized method in the superclass acquires the same lock as one in the subclass.

    【讨论】:

      【解决方案3】:

      This link to the JLS 确认我们不能混合抽象和同步。

      虽然比关键字或标准注释弱得多,但比文档强:也许试试Marker interface

      ... 提供了一种将元数据与一个类相关联的方法,其中 语言没有明确支持此类元数据。

      这是一个延伸,但可能会有所帮助,因为派生类进行了声明(编辑:新示例测试声明):

      interface EatMethodIsThreadSafe {}
      
      abstract class Animal {
          public Animal() {
              if (! (this instanceof EatMethodIsThreadSafe)) { 
                  throw new IllegalArgumentException("eat method must be thread safe");
              }
          }
          public abstract void eat();
      }
      
      public class Bear extends Animal implements EatMethodIsThreadSafe {
          public synchronized void eat() {}
          public static void main(String...args) { Bear b = new Bear(); } 
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-07-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-16
        • 1970-01-01
        相关资源
        最近更新 更多