【问题标题】:Java multi-threading confusionJava多线程混淆
【发布时间】:2015-05-14 11:31:00
【问题描述】:

代码示例 1:

class Test {
    MyObj myObj = new MyObj();

    public void test() {
        // doing my other stuff
        synchronized (myObj) {
            // accessing myObj
        }
    }
}

代码示例 2:

class Test {
    MyObj myObj = new MyObj();

    public void test() {
        synchronized (myObj) {
            // doing my other stuff

            // accessing myObj
        }
    }
}

代码示例 3:

class Test {
    MyObj myObj = new MyObj();

    public synchronized void test() {
        // doing my other stuff

        // accessing myObj
    }
}

我想在上面的代码快照中保持线程安全到 myObj。那么上面哪个代码快照更可取,为什么?

【问题讨论】:

  • 首选代码示例 1。代码示例 1 --> 在 myObj 上获取监视器,因此它是线程安全的 代码示例 2 --> 在 myObj 上获取监视器,因此它是线程安全的,内部或外部的其他内容无关代码示例 3 --> Lock/在调用 test() 方法的对象上获取监视器,无论是 myObj 还是其他任何对象,都取决于调用
  • 这些都不是可取的,因为您将 myObj 包保护而不是私有 =P

标签: java multithreading synchronize


【解决方案1】:

代码示例 1 是合适的。 因为持有对象的锁然后做一些其他的事情是不合适的。

【讨论】:

    【解决方案2】:

    根据我在开源项目中看到的代码,第一个代码示例更好,因为当您不再需要对象时,您释放它以便其他线程可以访问它。

    【讨论】:

      【解决方案3】:

      您的示例都没有包含足够的信息。

      数据在哪里?什么是不变量?线程何时/何地/如何访问数据?

      “线程安全”意味着没有数据就什么都不是。有状态类的文档通常会提供有关其方法如何推进实例状态的保证。 “线程安全”意味着即使方法被许多线程调用,这些保证也会得到满足。但是如果类不是有状态的,或者没有这样的保证,那么“线程安全”就没有任何意义。


      P.S.:与其他代码示例相比,代码示例 1 有一个重要优势:互斥体(即 synchronized 块)更小。根据经验,您希望互斥锁尽可能小。如果“我的其他东西”不关心受互斥体保护的数据,那么它不应该发生在互斥体中,因为这会阻止其他线程访问数据,并且会阻止它们无用的理由。


      P.P.S.:@Ordous 的评论 +1:没有办法知道某个对象的状态是否是线程安全的,除非您可以看到 每个可以修改或检查状态的代码块 .由于myObj 在您的示例中不是private,因此我们必须假设其他地方存在可以修改或检查其状态的代码。由于我们看不到该代码,我们必须假设 myObj线程安全的。

      【讨论】:

        【解决方案4】:

        锁定整个方法(如果它很长)是非常昂贵的。它不仅可以阻止整个威胁,还可以阻止不需要同步的代码。其次,有时您可能不会使用您的omyObj,在这种情况下,示例 2 和示例 3 会很糟糕。

        简而言之:只同步块的一部分,您正在使用您的对象。您还可以在对象上使用 volatile 来检查它的值,而无需同步块。请记住锁定成本很高

        但是当你的方法足够短,或者只包含带有 myObj 的代码时,让整个方法同步是一个很好的解决方案。

        public void test() {
           // doing my other stuff, not concernign myObj
            synchronized (myObj) {
                // do things with myObj (read/write)
            }
           // doing my other stuff, not concernign myObj
        }
        

        看看这个singleton 的例子。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-01-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多