JMX MBean - 在getter和setter上同步

时间:2013-01-23 01:37:45

标签: java thread-safety jmx

我只是想澄清一下我对JMX MBean的线程安全性的理解。

我有一个像这样简单的MBean:

public class Person
    implements PersonMBean
{
    private String name;

    public void setName(String name)
    {
        this.name = name;
    }

    public String getName()
    {
        return name;
    }
}

在可以有多个客户端访问MBean的情况下(例如,多个用户通过jconsole调用setName()),我确实需要同步getter和setter,对吗?

感谢。

3 个答案:

答案 0 :(得分:2)

同步可能不是您所需要的。同步定义了发生之前的关系,我认为这不是必需的。 所以

volatile private String name; 

可能已经足够了。

如果发生 - 在真正重要之前,我会选择fair reentrant lock


来自 JLS 3 8.3.1.4 volatile Fields

  

Java编程语言提供了第二种机制[除了同步],volatile   字段,这比某些目的的锁定更方便。

这可能是其中一个目的。

  

字段可以声明为volatile,在这种情况下是Java内存模型   (§17)确保所有线程都看到一致的值   变量

无论如何,请查看JLS中的 17.4.5 Happens-before Order ,并确定在这种情况下最适合您的方式。

答案 1 :(得分:1)

  

...可以有多个客户端通过jconsole调用[ing] setName(),我是否需要同步getter和setter?

是的,如果多个线程正在调用getter和setter,你可能应该这样做 - 就像多个本地线程正在调用getter和setter一样。正如@ user454322指出的那样,使用volatile关键字来完成内存同步也是合适的。

由于两个原因,某种形式的同步是必要的。首先,多个JMX操作可以同时运行,这意味着可以发生getter和setter竞争条件。其次,即使setter在getter之前发生,也无法保证JMX线程在没有同步的情况下具有更新的值。这取决于每个线程获取名称的最后一个值的重要性。如果所有线程都必须看到已设置的姓氏,那么您需要保持良好状态synchronized

这就是说,我们在统计数据和其他诊断信息上有很多不同步的JMX getter方法,并期望JVM在某些时候同步各种计数器。

答案 2 :(得分:1)

如果您的所有JMX bean都在设置字段的值,那么您需要做的就是将该字段声明为volatile。这可以确保对变量的后续读取可以看到先前的写入。

使方法synchronized也提供相同的保证,但需要额外的费用来获得监视器。