允许方法在 Java 中锁定其父对象

Posted

技术标签:

【中文标题】允许方法在 Java 中锁定其父对象【英文标题】:Allowing a method to lock its parent Object in Java 【发布时间】:2010-10-01 03:47:28 【问题描述】:

在 Java 中有没有办法获得一个方法来锁定(互斥)它所在的对象?

我知道这听起来令人困惑,但基本上我不想与 C# 的 sn-p 等效,而是在 Java 中。

lock(this)

    // Some code here...

我的任务是将 .Net 编写的 API 重新实现到 Java 中,并且我被要求尽可能使 Java 版本与 .Net 版本相似。 .Net 版本看起来像是从我无法访问的 C++ 版本转录的事实,这无济于事。

无论如何,上面的行出现在 C# 版本中,我需要在 Java 中做同样的事情。

【问题讨论】:

【参考方案1】:

相当于是:

synchronized (this)


(不,您通常不应该在 C# 或 Java 中执行此操作。更喜欢锁定私有引用,其他任何东西都无法访问。当然,您可能已经意识到这一点 - 但我不想在没有警告的情况下留下答案:)

【讨论】:

因为其他代码无法锁定您。这就像公开更多的方法一样 - 但更难调试,因为线程从根本上来说是困难的。 有关更多详细信息,请参阅 Effective Java 第二版中的第 70 项 - 以及当您确实必须使用公共引用作为 API 的一部分时如何锁定。跨度> 我已经阅读了该项目,但我仍然觉得“你通常不应该这样做”被夸大了(特别是考虑到问题的范围)。我会说:这是典型的做法。 “线程从根本上来说很难”是你几乎可以扔给任何东西的东西,但没有人会更聪明。 如果您想要公开锁,那是一回事 - 但除此之外,锁定其他人可能锁定的东西有什么好处?不必创建新对象有一个微小的好处——但基本上就是这样。另请参阅 Jeff Richter 通过 C# 编写的 CLR 的 P636-639。 是的,一个新问题可能会引发一些有趣的讨论。这与其说是“对还是错”问题,不如说是“防御性做法”。与许多最佳实践一样,对于类库设计(您不了解消费者)而言,这比直接的应用程序开发更重要。【参考方案2】:

假设 C++ 代码是一个简单的互斥体,将“lock”替换为“synchronized”

synchronized (this)

// ...

这里是Java Concurrency tutorial了解更多信息

【讨论】:

【参考方案3】:

我推荐 Brian Goetz 的“Java Concurrency In Practice”。这是一本很棒的书。

保持同步块尽可能小是件好事。在方法上使用 synchronized 修饰符是粗粒度的,有时是必要的,但否则您可以使用另一个对象来执行此操作,以保持块更小。

像这样:

public class PrivateLock 
    private final Object myLock = new Object();
    @GuardedBy("myLock") Widget widget;

    void someMethod() 
        synchronized (myLock) 
            // Access or modify the state of widget
        
    

【讨论】:

【参考方案4】:

您还应该查看 API (JDK 5.0+) 的 java.util.concurrent 包以获取其他并发管理对象,例如信号量、交换器等

http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/package-summary.html

【讨论】:

以上是关于允许方法在 Java 中锁定其父对象的主要内容,如果未能解决你的问题,请参考以下文章

同步使对象锁定

Java同步静态方法:锁定对象或类

java中,用synchronized会锁定当前对象,这个对象指的是它包涵的代码块,还是一个类实例

Java NIO FileLock 允许其他进程写入锁定的文件

有偏见的锁定设计决策

双重检查锁定