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

时间:2015-02-18 11:52:38

标签: java concurrency

这是我的情况:

我有一个循环,

在该循环内我需要验证条件

如果条件被验证,则调用2个方法(这些方法只需要调用一次)

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

请问如何避免这种情况?

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

3 个答案:

答案 0 :(得分:3)

由于这被标记为并发,我建议引入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]

答案 1 :(得分:0)

我希望通过奇怪的行为,你的意思是有时没有问题,而在其他时候,状态的随机变化是不可再现的。

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

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

答案 2 :(得分:0)

您可以使用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. 
}

如果同时调用您的方法的线程数很高,则可能表现不佳。