Reputation: 1257
I am received a request to fix sonar issues in a legacy project, there is a code segment like this, every call to this function will be paused for 50ms:
synchronized(monitor) {
[...]
try {
[...]
Thread.sleep(config.getWaitTime()); // return 50
} catch (SomeException e) {
log.error(e.getMessage(), e);
}
[...]
}
First, sonar asked me to change Thread.sleep()
to wait()
so I change the try block to to:
try {
[..]
monitor.wait(config.getWaitTime());
} catch (SomeException e) {
log.error(e.getMessage(), e);
}
Then, another issue appear : Remove this call to "wait" or move it into a "while" loop
, I do not have much experience with multithreading, so I'm not sure my fix is correct:
boolean wait = true;
while (wait) {
wait = false;
monitor.wait(config.getWaitTime());
}
Is the above solution correct? If not, what should I do?
Upvotes: 2
Views: 3721
Reputation: 20543
sonar asked me to change Thread.sleep() to wait()
Just ignore sonar here. It is false positive alarm.
Upvotes: 1
Reputation: 131496
Here the while
appears helpless :
boolean wait = true;
while (wait) {
wait = false;
monitor.wait(config.getWaitTime());
}
The while
statement around the wait()
statement is designed to check that the wait()
be re-invoked if the logical/function condition in the while
is true
but in your case it is never as you assign wait to false
as first statement of the while body.
The while
is so helpless.
Here is the Object.wait(long)
javadoc associated to :
A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious wakeup. While this will rarely occur in practice, applications must guard against it by testing for the condition that should have caused the thread to be awakened, and continuing to wait if the condition is not satisfied.
As often I am not convinced at all of Sonar advises....
You could use a timer to check that the required time was elapsed in the while. But ugg.
I advise you to keep the Thread way that suits to your requirement.
Or if you want to make the tool API add helpless code. Of course I am joking : don't do that !
Upvotes: 2
Reputation:
From the Object#wait() Java doc
A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious wakeup. While this will rarely occur in practice, applications must guard against it by testing for the condition that should have caused the thread to be awakened, and continuing to wait if the condition is not satisfied. In other words, waits should always occur in loops, like this one:
synchronized (obj) { while (<condition does not hold>) obj.wait(timeout); ... // Perform action appropriate to condition }
Your loop doesn't look good, it should be something like:
while (wait) {
monitor.wait(config.getWaitTime());
}
The wait
variable must be set from elsewhere, when the wait condition is no longer needed.
Upvotes: 2