Reputation: 2977
I need to provide mutual access to a method of a class, so one thread at time can execute the code inside the method. I have tried the solution below but I cannot understand why every time the value of the variable 'locked' is false.
public class MyCommand extends BaseCommand {
private static boolean locked=false;
@Override
public boolean execute() throws Exception {
synchronized(MyCommand.class){
while (locked){
wait();
}
locked=true;
//some code with a breakpoint/long blocking operations
locked=false;
notifyAll();
return true;
}
}
I have placed a breakpoint in the while statement at the beginning and the value of the variable locked is always false and I cannot understand why. The second breakpoint is in the body of the method and I use it in order to block the execution of the first thread and see the the value of the variable locked changed in the second thread, but unfortunately it is not happening. Therefore, as end results all the threads are able to execute this method without any thread safeness. Does anybody have an idea on how I can provide exclusive access to this method one thread per time?
Upvotes: 0
Views: 588
Reputation: 3147
The value is always false because only one thread at a time is executing the synchronized block so... when the first thread finished the variable is false again... then, the next thread reads false.
I prefer in this scenarios to use ReentrantLock, something like:
protected final ReentrantLock myLock= new ReentrantLock();
...
try {
//wait until i have the lock
this.myLock.lock();
//do some stuff
} finally {
//release the lock
this.myLock.unlock();
}
And in this article you could see the big difference in performance between synch section and ReentrantLock: http://lycog.com/concurency/performance-reentrantlock-synchronized/
Upvotes: 1
Reputation: 40500
Only one thread is inside the synchronized block at a time, right?
You stop your thread at the beginning of the block, and check the value of locked
. Well, if your thread is inside the block, that means that no other thread is. And if no other thread is inside, then locked
has to to be false, that's the whole point. Why does it surprise you?
You don't need the while(locked) wait()
loop by the way (or the whole locked
thing for that matter) exactly for the reason described above - the whole "locking" is achieved by having the synchronized
lock around your code.
Upvotes: 4