Java 中枚举值的线程安全比较
Thread-safe comparison of an enum value in Java
这是我当前的代码。我想了解如果 getState()
已经同步,是否需要将 isObjectActive()
包装在同步块中?
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;
}
}
[Do] I need to wrap isObjectActive() in a the synchronized block...?
没有
同步不是针对方法,而是针对数据。在上面显示的示例中,您可以从 isObjectActive()
中删除 synchronized
块,因为该函数不直接访问 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(...);
}
这是我当前的代码。我想了解如果 getState()
已经同步,是否需要将 isObjectActive()
包装在同步块中?
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;
}
}
[Do] I need to wrap isObjectActive() in a the synchronized block...?
没有
同步不是针对方法,而是针对数据。在上面显示的示例中,您可以从 isObjectActive()
中删除 synchronized
块,因为该函数不直接访问 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(...);
}