Java 将同步方法转换为非阻塞算法

Java 将同步方法转换为非阻塞算法,java,multithreading,synchronization,nonblocking,atomicreference,Java,Multithreading,Synchronization,Nonblocking,Atomicreference,只要找到一些关于非阻塞算法的信息,就可以在实践中使用它们。我把一些代码从同步改为非阻塞,所以我想问一下,我是否把一切都做好了,并保存了以前的功能 同步代码: protected PersistentState persistentState; protected ClassConstructor(final ID id) { super(id); this.persistentState = PersistentState.UNKNOWN; } public final sync

只要找到一些关于非阻塞算法的信息,就可以在实践中使用它们。我把一些代码从同步改为非阻塞,所以我想问一下,我是否把一切都做好了,并保存了以前的功能

同步代码:

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();
    }
我的非阻塞算法选择:

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();
    }
受保护的原子引用persistentState;
受保护的类构造函数(最终ID)
{
超级(id);
this.persistentState=新原子引用(persistentState.UNKNOWN);
}
公共最终PersistentState getPersistentState()
{
返回此.persistentState.get();
}
受保护的void setPersistentState(最终PersistentState newPersistentState)
{
PersistentState tmpPersistentState;
做
{
tmpPersistentState=this.persistentState.get();
}
而(!this.persistentState.compareAndSet(tmpPersistentState,newPersistentState));
//this.persistentState.set(newPersistentState);不需要时删除
notifyPersistentStateChanged();
}

我做的每件事都是正确的,还是遗漏了什么?对代码和使用非阻塞方法设置abject有什么建议吗?

取决于您所说的线程安全。如果两个线程试图同时写入,您希望发生什么?是否应随机选择其中一个作为正确的新值

最简单的就是这样

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

取决于线程安全的
含义。如果两个线程试图同时写入,您希望发生什么?是否应随机选择其中一个作为正确的新值

最简单的就是这样

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

您不应使用“this.persistentState.set(newPersistentState)”作为比较数据集更新persistentState的值。只有在将值设置为newPersistentState后,比较数据集才会中断while循环,因此,如哈恩所述,无需再次将其设置为newPersistentState。如果需要,那么这将是一种先检查后行动的方式,很容易出现过时的数据问题。谢天谢地,它不是。您不应该使用“this.persistentState.set(newPersistentState)”作为比较数据集更新persistentState的值。只有在将值设置为newPersistentState之后,比较数据集才会中断while循环,因此,如哈恩所述,不需要再次将其设置为newPersistentState。如果需要,那么这将是一种先检查后行动的方式,很容易出现过时的数据问题。谢天谢地不是。我只需要在更改时通知。顺便说一句,我是否很清楚,在我的例子中,如果线程想要设置相同的值,我将得到无限循环?@Edgar-no。如果tmOperateSistentState与newPersistentState相同,那么您的循环就可以正常工作。只要this.persistentState与tmpPersistentState相同,它就会返回true和breakout。不应该有无限循环。我只需要在更改时通知。顺便说一句,我是否很清楚,在我的例子中,如果线程想要设置相同的值,我将得到无限循环?@Edgar-no。如果tmOperateSistentState与newPersistentState相同,那么您的循环就可以正常工作。只要this.persistentState与tmpPersistentState相同,它就会返回true和breakout。不应该有无限循环。