Java: 如何避免方法在循环中被调用两次

Java: how to avoid method being called twice in loop

这是我的情况:

我有一个循环,

在该循环中我需要验证一个条件

如果条件成立调用2个方法(方法只需要调用一次)

由于应用程序有奇怪的行为,我怀疑循环太快,并且这些方法可能被调用不止一次

请问如何避免这种情况?

@Override
    public void loop() {
        Thread.sleep(1000);
        if (thisIsTrue()) {                //Condition checked
            setThisFalse();                 //Set the condition above false
            thanDoSomethingElse();         //Method to executed ONLY ONCE
        }
    }

由于这被标记为并发,我建议引入一个 synchronized 块:

private Object conditionSync = new Object();

@Override
public void loop() {
    Thread.sleep(1000);
    synchronized(conditionSync) {
        if (thisIsTrue()) {                //Condition checked
            setThisFalse();                 //Set the condition above false
            thanDoSomethingElse();         //Method to executed ONLY ONCE
        }
    }
}

但是,请确保访问或修改 thisIsTrue()setThisFalse() 中使用的变量的所有方法也以同步方式访问它。重新设计应用程序并引入检查和修改变量的单一方法可能会更好。

另一种选择是使用AtomicBoolean.compareAndSet() [Oracle]

我希望你说的奇怪行为是指有时没有问题,而有时状态随机变化,无法重现。

如果是,那么很可能您遇到了与多个线程同时修改状态相关的问题。在这种情况下,最终结果取决于无法预测的操作时间。

您可以同步对变量的访问 'thisIsTrue' 方法正在评估并确保检查值和修改值以原子方式发生。如果您不熟悉同步结构,可以阅读 oracle 的同步教程。java。

您可以使用 AtomicBoolean 保护您的方法调用。

这是一个示例代码:

final AtomicBoolean executed = new AtomicBoolean(false); 
// this is not a variable defined in a method. If your code will be called by 
// multiple threads, those threads must have access to this variable. 

if (executed.compareAndSet(false, true)) {
     // call your method here. It is guaranteed to be called only once. 
}

如果并发调用您的方法的线程数很高,这可能会执行不佳。