只是找到有关非阻塞算法的信息,所以想在实践中使用它们。我将一些代码从同步更改为非阻塞,因此我想问一下我是否做对了所有事情并保存了以前的功能。

同步代码:

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();
    }


我是否已正确完成所有操作,还是错过了某些内容?对于代码和使用非阻塞方法设置对象一般有什么建议吗?

最佳答案

取决于thread-safe的意思。如果两个线程尝试同时写入,您想发生什么?是否应随机选择其中之一作为正确的新值?

最简单的就是这样。

protected AtomicReference<PersistentState> persistentState = new AtomicReference<PersistentState>(PersistentState.UNKNOWN);

public final PersistentState getPersistentState() {
    return this.persistentState.get();
}

protected void setPersistentState(final PersistentState newPersistentState) {
    persistentState.set(newPersistentState);
    notifyPersistentStateChanged();
}

private void notifyPersistentStateChanged() {
}


在所有情况下,即使状态没有更改,它仍将调用notifyPersistentStateChanged。您需要确定在那种情况下应该发生什么(一个线程使A-> B,而另一个线程使B-> A)。

但是,如果仅在成功转换值后才需要调用notify,则可以尝试如下操作:

 protected void setPersistentState(final PersistentState newPersistentState) {
    boolean changed = false;
    for (PersistentState oldState = getPersistentState();
            // Keep going if different
            changed = !oldState.equals(newPersistentState)
            // Transition old -> new successful?
            && !persistentState.compareAndSet(oldState, newPersistentState);
            // What is it now!
            oldState = getPersistentState()) {
        // Didn't transition - go around again.
    }
    if (changed) {
        // Notify the change.
        notifyPersistentStateChanged();
    }
}

关于java - 将同步方法转换为非阻塞算法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36697938/

10-10 12:53