代码之家  ›  专栏  ›  技术社区  ›  Adam Goode

在Java中,如何在每次进入或退出给定对象的监视器时记录消息?

  •  4
  • Adam Goode  · 技术社区  · 14 年前

    我试图调试一些使用自定义refcounting/locking的C/Java绑定。我想让JVM在每次给定对象的监视器进入或退出时打印一条消息。有什么办法吗?基本上,我想要这个:

    synchronized(lock) {
       ...
       System.out.println("hi");
       ...
    }
    

    要打印此文件:

    *** "lock" monitorenter
    hi
    *** "lock" monitorexit
    

    我已经看过了 XX 但什么也没找到。这是openjdk6。

    6 回复  |  直到 14 年前
        1
  •  2
  •   aioobe    14 年前

    问得好。我能想到的唯一解决办法基本上是:

    ASM . (ASM提供了一个很好的示例,说明如何在类装入器中使用字节码重写。)

    System.out.println 每次之前 monitorenter monitorexit

    多亏了ASM库中良好的访问者模式,这不应该超过一两屏代码。

        2
  •  0
  •   bwawok    14 年前

    尝试通过创造性地使用print语句来调试concurreny问题是一场失败的战斗,因为print语句可能有自己的并发错误,并且不能按预期的顺序打印。试图调试或打印出一个concurreny bug听起来不错,但我不认为它会得到你想要的结果。你需要用仔细的思考和逻辑来证明你的代码是正确的(更多的是计算机科学而不是软件工程)。

    并发问题非常困难。如果您在实践中没有读过并发,请确保您已经读过它。然后看看所有可能的方法,你的同步块可以达到,所有的事情,它可以改变的范围以外的锁,等等。

        3
  •  0
  •   Thorbjørn Ravn Andersen    14 年前

    不幸的是,这需要Solaris或OSX。

    幸运的是,OpenSolaris仍然可以下载并在虚拟机中运行。它在VirtualBox中运行得最好。

        4
  •  0
  •   Thierry Roy    14 年前

    我认为在java中没有绑定到“锁定”事件的方法。但你可以看看java.lang.management语言各种锁定信息。例如,有 ThreadMXBean.findDeadlockedThreads()

        5
  •  0
  •   teto    14 年前

    除非您编写自己的锁类(或修改现有的锁类),否则我的猜测是很难做到您想要的,特别是如果您在监视器对象上使用同步块而不是锁类。但是,您可以使用JDK提供的jstack命令在运行时分析流程,请检查 here 对于手册页,还有JVM选项-XX:-printcurrentlocks,用于在使用Ctrl Break停止JVM进程时打印锁(更多选项) here ).

        6
  •  0
  •   Saurabh    14 年前

    我建议您实现Lock类的现有实现或实现自己的实现( http://download.oracle.com/javase/tutorial/essential/concurrency/newlocks.html ). 现在可以重写lock and unlock方法。因此,不要使用同步的方法/语句,而是使用此功能,并在锁定/解锁方法中放入日志:)