当前位置: 首页 > 知识库问答 >
问题:

可重入锁-Java并发在实践中的应用

冯元魁
2023-03-14
class Widget {
public synchronized void doSomething() {
    System.out.println(toString() + ": calling superclass doSomething");
}


}

class LoggingWidget extends Widget {
public synchronized void doSomething() {
    System.out.println(toString() + ": calling subclass doSomething");
    super.doSomething();
}
}

书中解释了在上面的代码中...“因为Widget和LoggingWidget中的doSomething方法都是同步的,所以在继续之前,每个方法都试图获取小部件上的锁。”

我运行了上面的代码来观察内部锁。上面的引文似乎暗示线程在Widget对象上获得了一个内在锁,但我观察到的是线程在LoggingWidget上获得了一个锁。我不知道如何核实收购数量,所以无法观察到这一点。

这本书是可以互换地使用loggingwidget/Widget这两个名称,还是应该专门观察Widget对象上的锁?

编辑:全文摘录

可重入性方便了锁定行为的封装,从而简化了面向对象并发代码的开发。如果没有可重入锁,清单2.7中看起来非常自然的代码(其中子类重写synchronized方法,然后调用超类方法)将会死锁。因为Widget和LoggingWidget中的doSomething方法都是同步的,所以在继续之前,每个方法都尝试获取小部件上的锁。但是,如果内部锁不是可重入的,那么对super.doSomething的调用将永远无法获得锁,因为它将被认为已经被持有,线程将永久停顿,等待一个它永远无法获得的锁。在这种情况下,重入可以避免死锁。

共有1个答案

秦滨海
2023-03-14

我需要看一下摘录才能给你一个具体的答案。您可以用不同的方式实例化这些类。对象上持有锁,因此引用是什么并不重要。为了说明...

这个类结构与你的类结构非常相似。

public class GenericTest {
    public static void main(String... args) {
        Sub sub = new Sub();
        sub.go();
    }

    public synchronized void go() {
        System.out.println("Parent");
    }
}

class Sub extends GenericTest {
    @Override
    public synchronized void go() {
        System.out.println("Child");
        super.go();
    }
}

运行这个程序,并在使用您喜欢的方法(例如System.in.Read())获得锁后停止执行更多行。找到java程序的pid并在JConsole中打开它。移动到Threads部分,并在每次获取锁时突出显示它。你会看到下面的痕迹。

my.package.common.GenericTest.go(GenericTest.java:30)
   - locked my.package.common.Sub@4c767286
my.package.common.Sub.go(GenericTest.java:42)
   - locked my.package.common.Sub@4c767286
 类似资料:
  • 本文向大家介绍Java并发编程之ReentrantLock可重入锁的实例代码,包括了Java并发编程之ReentrantLock可重入锁的实例代码的使用技巧和注意事项,需要的朋友参考一下 目录 1.ReentrantLock可重入锁概述2.可重入3.可打断4.锁超时5.公平锁6.条件变量 Condition 1.ReentrantLock可重入锁概述 相对于 synchronized 它具备如下特

  • 问题内容: 在《 Java Concurrency In Practice》中,作者指出 不变对象可以通过任何机制发布 不可变对象可以在没有附加同步的情况下被任何线程安全地使用,即使不使用同步来发布它们。 这是否意味着以下成语可以发布不可变对象? 会有数据竞赛吗?(这意味着线程B可能无法在线程A添加的列表中看到不可变对象) 非常感谢你。 此外,作者说,如果Resource是不可变的,以下代码是安全

  • null 对于此问题的第二部分,将在另一个问题(单击此处)中详细讨论

  • 我在学习Java中的重入锁定。需要一定的澄清这个概念,它实际上是如何工作的。下面的片段我所理解的是:

  • 问题内容: Brian Goetz的Java Concurrency in Practice提供了一个有效的可伸缩缓存供并发使用的示例。这是该类的代码: 可能是个愚蠢的问题,但有人能告诉我该类的并发用法吗?喜欢在主? 干杯,Agata 问题答案: 这是一个计算阶乘的示例: 因此,如果两个线程尝试在完全相同的时间计算相同的阶乘,则由于线程安全,因此只有其中一个将实际执行计算。第二个线程将简单地获取第

  • 主要内容:1 什么是Java可重入锁,2 Java可重入锁的优势,3 Java可重入锁的例子1 什么是Java可重入锁 根据Sun公司的说法,Java锁是可重入的,这意味着,如果从方法中调用方法,则Java线程可以将同一把锁用于不同的同步方法。 2 Java可重入锁的优势 它避免了单线程死锁。 3 Java可重入锁的例子 让我们通过以下示例了解Java可重入锁: 在此类中,m和n是同步方法。m() 方法在内部调用n() 方法。 现在让我们在线程上调用m() 方法。在下面给出的类中,我们使