【发布时间】:2016-04-18 15:11:33
【问题描述】:
随便找一些关于非阻塞算法的资料,所以想在实践中使用。我将一些代码从同步更改为非阻塞,所以我想问一下我是否将所有内容都正确并保存了以前的功能。
同步代码:
protected PersistentState persistentState;
protected ClassConstructor(final ID id)
{
super(id);
this.persistentState = PersistentState.UNKNOWN;
}
public final synchronized PersistentState getPersistentState()
{
return this.persistentState;
}
protected synchronized void setPersistentState(final PersistentState newPersistentState)
{
if (this.persistentState != newPersistentState)
{
this.persistentState = newPersistentState;
notifyPersistentStateChanged();
}
}
我在非阻塞算法中的替代方案:
protected AtomicReference<PersistentState> persistentState;
protected ClassConstructor(final ID id)
{
super(id);
this.persistentState = new AtomicReference<PersistentState>(PersistentState.UNKNOWN);
}
public final PersistentState getPersistentState()
{
return this.persistentState.get();
}
protected void setPersistentState(final PersistentState newPersistentState)
{
PersistentState tmpPersistentState;
do
{
tmpPersistentState = this.persistentState.get();
}
while (!this.persistentState.compareAndSet(tmpPersistentState, newPersistentState));
// this.persistentState.set(newPersistentState); removed as not necessary
notifyPersistentStateChanged();
}
我做的一切都是正确的,还是我错过了什么?对代码和使用非阻塞方法设置 abject 有什么建议吗?
【问题讨论】:
-
你不应该使用 "this.persistentState.set(newPersistentState)" 作为 compareAndSet 更新persistentState的值
-
compareAndSet 只有在将值设置为 newPersistentState 后才会跳出 while 循环,因此不需要像哈恩提到的那样再次将其设置为 newPersistentState。如果需要,那么这将是一种检查然后采取行动的方式,容易出现过时的数据问题。幸好不是。
标签: java multithreading synchronization nonblocking atomicreference