Reputation: 4595
This is my situation:
I have a loop,
inside that loop I need to verify a condition
if the condition is verified call 2 methods (the methods need to be called only once)
Since the application is having strange behaviors I suspect the loop is too fast, and the methods might be called more than once
Please how to avoid this??
@Override
public void loop() {
Thread.sleep(1000);
if (thisIsTrue()) { //Condition checked
setThisFalse(); //Set the condition above false
thanDoSomethingElse(); //Method to executed ONLY ONCE
}
}
Upvotes: 0
Views: 2542
Reputation: 391
You can guard your method call with an AtomicBoolean.
Here is a sample code:
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.
}
If number of threads that concurrently call your method is high, this may perform poorly.
Upvotes: 0
Reputation: 59303
Since this is tagged as concurrency, I suggest introducing a synchronized block:
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
}
}
}
However, make sure that all methods that access or modify the variable used in thisIsTrue()
and setThisFalse()
also access it in a synchronized way. It might be better to redesign the application and introduce a single method that checks and modifies the variable.
Another option is the use of AtomicBoolean.compareAndSet() [Oracle]
Upvotes: 3
Reputation: 9317
I hope by strange behaviors you mean sometimes there is no problem while at other times there are random changes in state which are not reproducible.
If yes then most likely you are having problems related to multiple threads modifying state at same time. In such situation the final outcome depends on timing of operations which is not predictable.
You can synchronize the access to the variable 'thisIsTrue' method is evaluating and make sure that checking the value and modifying the value happen atomically. If you are not familiar with synchronization constructs, you can go through oracle's tutorials on java synchronization.
Upvotes: 0