简体   繁体   中英

Mutual thread exclusion in a JAVA method

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?

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.

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/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM