Ashish Pancholi
Ashish Pancholi

Reputation: 4649

when thread calls wait it releases the lock versus race condition

According to the basic definition of synchronized method from source - link

"When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object."

and I read about the wait() that it releases a lock before it sleeps. There is a confusion here if wait releases the lock then other thread can get-into the synchronized method and does it make sense because it may lead to race condition?

Here is my sample code that is allowing one and two thread into the synchronized block.

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author Ashish Pancholi
 */
public class Test {

    public Test() {
        Sharing sharing = new Sharing();
        Worker worker_ = new Worker(sharing);
        Thread thread_ = new Thread(worker_, "one");
        Worker worker = new Worker(sharing);
        Thread thread = new Thread(worker, "two");
        thread_.start();
        thread.start();
    }

    public static void main(String[] argu) {
        Test test = new Test();
    }

    public class Worker implements Runnable {

        private Sharing sharing;

        public Worker(Sharing sharing) {
            this.sharing = sharing;
        }

        @Override
        public void run() {
            sharing.check();
        }
    }

    public class Sharing {

        public void check() {
            synchronized (this) {
                System.out.println("Thread IN " + Thread.currentThread().getName());
                try {
                    wait(5000);
                } catch (InterruptedException ex) {
                }
                System.out.println("Thread OUT " + Thread.currentThread().getName());
            }
        }
    }
}

Output-

Thread IN one
Thread IN two
Thread OUT one
Thread OUT two

Upvotes: 0

Views: 784

Answers (3)

René Link
René Link

Reputation: 51333

Yes it makes sense.

The API of the wait() method says:

Causes the current thread to wait until either another thread invokes the notify() method or the notifyAll() method for this object, or a specified amount of time has elapsed.

So if the wait method would NOT release the lock on the monitor object, no other thread could get it and thus no other thread could invoke notify or notifyAll on that monitor object.

The wait(5000) means that the current thread will wait up to 5000 milliseconds for a notification before continuing or continue after 5000 ms. If you want to hold the lock and pause 5000 ms then you must use Thread.sleep(5000).

Upvotes: 2

Geo
Geo

Reputation: 760

It makes sense that there might be race conditions. Race conditions naturally happen when dealing with multiple threads. It is your job to prevent them by carefully managing your threads, and the wait method is an important tool that you can use to help with that.

Normally you wouldn't simply call wait with a fixed 5-second pause like that. In a real application you would probably be waiting for some specific condition to be true, so your wait looks more like this:

try {
    while(!condition) {
       wait();
    }
    doSomething();
} catch(InterruptedException e) {
    doSomethingElseWhenWeAreAskedNotToWait();
}

Whether you have a race condition depends upon when condition becomes true, who else might be waiting for that condition, and what everyone does when it happens. The reason wait gives up the lock is to give condition a chance to become true while we wait.

Upvotes: 1

NPE
NPE

Reputation: 500197

You are using synchronized with two different locks, so there is no synchronization happening between the two threads.

Synchronize on the instance of Test rather than Sharing, and the behaviour will be quite different.

Upvotes: 0

Related Questions