【问题标题】:Is using explicit locks considered expensive?使用显式锁被认为是昂贵的吗?
【发布时间】:2020-01-21 01:53:03
【问题描述】:

有人提到,对对象级锁使用显式锁声明是一种很好的做法。但是,我认为对于我们创建的每个对象实例,我们最终都会为锁创建一个新对象并通过锁访问我们的方法,这都是昂贵的步骤。

但是,在同步方法的情况下,我相信没有任何事情,你使用对象自己的锁,你只需支付获取锁的成本。您避免创建显式锁定对象。

我这里有什么遗漏吗?

public class DemoClass
{
    private final Object lock = new Object();
    public void demoMethod(){
        synchronized (lock)
        {
            //other thread safe code
        }
    }
}

【问题讨论】:

  • 我很困惑你在这里真正问的是什么。您为每个 DemoClass 实例创建一个额外的对象(除非您创建数百万,那又如何);每次调用demoMethod 时,您都不会创建新锁。如果你需要互斥,你需要like这样的东西;那么更便宜的选择是什么?
  • 有时,您希望对对象状态执行操作,并且需要保护其免受并发性影响。静态实用程序方法可能不够用。我想这里的问题是检查同步方法是否比我上面定义的方法更好。两者都可以实现锁定。
  • synchronized (lock) 几乎不比synchronized (this) 贵。 new Object() 不被认为是昂贵的。为DemoClass 的每个实例创建一个额外的对象是否昂贵?它确实会产生更多的垃圾,但通常并不认为它很昂贵。基本上,使用单独的对象进行锁定是有成本的,但成本通常不会被认为是昂贵,但它实际上取决于您创建了多少DemoClass 实例。如果您要创建数百万个,那么成本是一个需要考虑的因素,否则就不是。
  • @AndyTurner 更便宜的选择是使用synchronized (this),即不需要额外的对象。
  • @TheRoy 作为首选,尽量简单,即使用synchronized:如果它的性能非常糟糕,那它就不会存在。私人锁为您提供更多控制和灵活性,但在很多情况下,您根本不需要它。

标签: java multithreading java-threads


【解决方案1】:

使用显式锁被认为是昂贵的吗?

一般来说,不会。它不被认为是昂贵的。 (取模不同的人有不同的看法,不同的应用有不同的要求。)

Object 实例的成本大约是 8 字节内存加上持有对父对象中锁的引用的变量的内存。总共是 12 或 16 个字节。

创建一个锁Object 实例的成本是……几纳秒。 (不完全确定有多少,但这是微不足道的。)

当锁Object 实例变成垃圾时,回收它的成本通常为零。 (当锁和它的父对象不是垃圾时,就会产生GC成本……)

除非您拥有数百万个此类对象过高的对象周转率您有严重的内存或延迟限制,否则这些成本都是微不足道的。

(或者如果您决定在不需要锁定的东西上放置/使用锁。但这是一个不同的问题。)

在显式锁对象上获取或释放锁的成本与在this 上获取/释放锁的成本差异很小(AFAIK)。也许是一次内存访问。


对于典型应用程序,这些成本差异无关紧要。将会有更重要的事情需要优化。标准建议适用:

  • 编码简单1开始。简单更易于编写和调试......和阅读。
  • 避免过早优化;例如在您编写代码时。
  • 在优化之前对您的应用程序进行基准测试和分析。
  • 使用测量结果来决定哪些值得优化。

与锁定this 可能导致的潜在问题相比,性能问题可能微不足道。实际上,这取决于您的应用程序复杂性和实现细节。


1 - 对您和您的同事来说足够简单。它取决于上下文。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-28
    • 2015-02-13
    • 1970-01-01
    • 1970-01-01
    • 2014-05-19
    • 2010-12-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多