这是我的情况:
我有一个循环,
在该循环内我需要验证条件
如果条件被验证,则调用2个方法(这些方法只需要调用一次)
由于应用程序有奇怪的行为,我怀疑循环太快,并且可能不止一次调用这些方法
请问如何避免这种情况?
@Override
public void loop() {
Thread.sleep(1000);
if (thisIsTrue()) { //Condition checked
setThisFalse(); //Set the condition above false
thanDoSomethingElse(); //Method to executed ONLY ONCE
}
}
答案 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()
中使用的变量的所有方法也以同步方式访问它。重新设计应用程序并引入一种检查和修改变量的方法可能会更好。
答案 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.
}
如果同时调用您的方法的线程数很高,则可能表现不佳。