potterhead
potterhead

Reputation: 11

Synchronized keyword not working as expected when monitor object is shared between multiple threads

I am practicing java multi threading and concurrency. So I am currently working on wait() and notify() functionality. I have created below code


public class WaitAndNotifyTest {

    public static void main(String[] args) {
        Object testString = new Object();
        RunnableImplTest runnableImplTest = new RunnableImplTest(testString);
        for(int i=0; i<5; i++) {
            Thread thread = new Thread(runnableImplTest);
            System.out.println("Created thread " + thread.getName());
            thread.start();
        }
        
        synchronized (testString) {
            testString.notify();
        }

    }
    
    private static class RunnableImplTest implements Runnable{
        
        private Object str;
        
        public RunnableImplTest(Object str) {
            this.str = str;
        }

        @Override
        public void run() {
            try {
                synchronized (str) {
                    System.out.println("Sending in waiting state for thread "+Thread.currentThread().getName());
                    str.wait();
                    System.out.println("Waiting completion for thread " + Thread.currentThread().getName());
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Got the control for "+Thread.currentThread().getName());
            
        }
        
    }

}

I have created this code to check how notify() selects the one thread from the list of waiting threads to allow further execution.

Now I am getting below output for the above code

Created thread Thread-0
Created thread Thread-1
Created thread Thread-2
Sending in waiting state for thread Thread-0
Created thread Thread-3
Sending in waiting state for thread Thread-1
Created thread Thread-4
Sending in waiting state for thread Thread-2
Sending in waiting state for thread Thread-3
Sending in waiting state for thread Thread-4
Waiting completion for thread Thread-0
Got the control for Thread-0

According to my code I was expecting that synchronized keyword should lock on the monitor object for thread-X and any other thread should not be allowed to enter that block in their own instances of RunnableImplTest as I have shared the monitor object across multiple threads.

Upvotes: 1

Views: 61

Answers (2)

Thomas Kl&#228;ger
Thomas Kl&#228;ger

Reputation: 21435

This is documented in the JavaDoc for Object.wait() (note added emphasis):

This method causes the current thread (referred to here as T) to place itself in the wait set for this object and then to relinquish any and all synchronization claims on this object.

Note that this is required: how else could the main thread execute

    synchronized (testString) {
        testString.notify();
    }

if the lock on testString was still held by any of the threads that you started.

BTW testString is a terrible name: it is not a string, it doesn't have anything to do with tests, it distracts from understanding its purpose.

Upvotes: 3

Izruo
Izruo

Reputation: 2276

The wait() method relinquishes the lock held by the thread on that object.

From Object#wait(long,int):

This method causes the current thread (referred to here as T) to place itself in the wait set for this object and then to relinquish any and all synchronization claims on this object.

Upvotes: 0

Related Questions