Java 为什么';电子表格封面同步化(MyClass.class)?

Java 为什么';电子表格封面同步化(MyClass.class)?,java,concurrency,code-coverage,synchronized,emma,Java,Concurrency,Code Coverage,Synchronized,Emma,我正在使用EclEmma进行覆盖率分析 我的Java代码包含一个同步(MyClass.class){}块 EclEmma说这只是部分内容,尽管我有一个单元测试,其中一个线程可以访问,另一个线程被阻塞 使用EclEmma是否可以获得同步的全部覆盖 我可以用某种方式对代码进行注释,让EclEmma完全覆盖这一行吗 问候 罗杰我不确定是否有可能得到全面报道,因为有报道说: EMMA总是将同步(…)标记为部分覆盖 示例: 也许不同的工具()会产生不同的结果?(我最近没有测试过) 2012年12月更新(

我正在使用EclEmma进行覆盖率分析

我的Java代码包含一个同步(MyClass.class){}块

EclEmma说这只是部分内容,尽管我有一个单元测试,其中一个线程可以访问,另一个线程被阻塞

使用EclEmma是否可以获得同步的全部覆盖

我可以用某种方式对代码进行注释,让EclEmma完全覆盖这一行吗

问候
罗杰

我不确定是否有可能得到全面报道,因为有报道说:

EMMA总是将
同步(…)
标记为部分覆盖

示例:

也许不同的工具()会产生不同的结果?(我最近没有测试过)


2012年12月更新(超过2年后):

:

如果同步的块包含在对象监视器上等待的代码,并且测试中断了等待的线程,则同步的
synchronized
将变为绿色


经过一点实验,如果
synchronized
块正常完成,并且由于异常而突然完成,我就能够完全覆盖
synchronized


我认为问题在于
MyClass.class
,它显然是使用

由于隐藏类.forName()而导致的隐式分支。这个案子是 这很不幸,因为这很常见,但是程序员 几乎没有控制权

因为Class.forName()可以抛出已检查的异常,所以编译器 发出一个捕捉块,将其作为未选中状态重新缩回。这个挡块 几乎从未在实践中执行过,但它成功地划清了界限 部分覆盖

我在第一次通读时错过了

我将尝试重新编写我的代码以获得全面覆盖


/罗杰

EclEmma使用下面的Jacoco进行覆盖率分析

如Jacoco(目前不存在)所述,该行为是为同步块生成的字节码的结果:

Java同步块被编译成两条字节码指令:块开头的MONITORENTER和块结尾的MONITOREXIT

为了确保在任何情况下都释放监视器,安装了指向另一条MONITOREXIT指令的异常处理程序。这个异常处理程序块通常会导致部分行覆盖,这从源代码的角度看是没有意义的

如@nathan ryan:

  • 正常执行同步块的一个测试
  • 第二个测试,从同步块内引发(因此期望)异常

  • 看来你是对的。我试过:objectsynch=MyClass.class;synchronized(synch){}但它没有帮助,即使我的测试有一个线程正在等待,另一个线程正在获取互斥。根据我的经验,如果synchronized块包含在对象监视器上等待的代码,并且测试中断了等待的线程,
    synchronized
    将变为绿色。然而,我从来没有费心钻研过EMMA仪器,以确定这在一般情况下是否正确。经过一点实验,如果同步块正常完成,并且由于异常而突然完成,我能够实现
    同步
    行的完全覆盖。@NathanD.Ryan有趣。我已将您的评论包含在答案中,以提高可视性。@NathanRyan您能分享一个例子吗?(嗨,Arie)。所以Jacoco不明白控制流是安全的:如果你到达入口点,你就会到达出口点。我想象一个带有局部变量的块被编译成一个初始化局部变量、执行主体并清除局部变量的块,在该块周围包装一个额外的隐式异常处理程序,在发生异常时清除局部变量。这在风格上似乎完全相同;然而,您可以通过“执行”一个块来获得对它的完全覆盖。(我们的Java测试覆盖率工具为源代码提供工具,不会混淆)。
    synchronized (lock) // partially covered (yellow line in EclEmma)
    {
    // ...
    }
    synchronized (this) // partially covered (yellow line in EclEmma)
    {
    // ...
    }