Java中枚举值的线程安全比较

时间:2019-08-27 13:35:29

标签: java enums thread-safety synchronized

这是我当前的代码。我想了解如果isObjectActive()已经同步了,是否需要将getState()包装在一个同步块中?

private final Object lock = new Object();
@GuardedBy("lock")
private EventTypes state;

@GuardedBy("lock")
public void setState(final EventTypes state) {
    synchronized (lock) {
        this.state = state;
    }
}

@GuardedBy("lock")
@VisibleForTesting
public EventTypes getState() {
    synchronized (lock) {
        return state;
    }
}

@GuardedBy("lock")
public boolean isObjectActive() {
    synchronized (lock) {
        return getState() == EventTypes.ACTIVE;
    }
}

1 个答案:

答案 0 :(得分:2)

  

[我需要将isObjectActive()包装在一个同步块中吗??

否。

同步不适用于方法,而是用于数据。在上面显示的示例中,您可以从synchronized中删除isObjectActive()块,因为该函数不会直接访问state变量,并且它调用的唯一其他函数是 在访问state时使用同步。

@Thomas在他对您的问题的评论中指出了一个要点:您可能应该考虑一下isObjectActive()调用的结果是否意味着其他线程的操作可以改变线程的状态。对象,然后调用者才有机会对结果采取行动:

MyType mt = ...;

if (mt.isObjectActive()) {
    // This is broken because there's no guarantee that mt still will be "active"
    // by the time doSomething...() gets called.
    //
    doSomethingThatOnlyMakesSenseWhen_mt_IsActive(...);
}