Madz
Madz

Reputation: 199

synchronized object

I have simple code:

public class testing {
    private static Object objToSync = new Object();

    public static void main(String[] args) {
        String obj1 = null;
        synchronized(objToSync){
            System.out.println("something one");                    
            doSomething();
            System.out.println("something three ");         
        }

        doSomething();      
    }

    private static void doSomething() {
        synchronized(objToSync){
            System.out.println("something two");
        }       
    }

I have read several things but still getting confused with this one. Why does the doSomething in the main gets called? Is it not suppose to wait till the synchronized object gets unlocked? Sorry if I am sounding stupid, i am just confused.

Upvotes: 1

Views: 7524

Answers (4)

Kumar Vivek Mitra
Kumar Vivek Mitra

Reputation: 33544

Locks are reentrants for the same thread. That means a thread which has gained the lock of an object can access this and any other synchronized methods (or atomic statements, like here in your example) of the object. This thread will not need to gain the lock again, once it has gotten it.

Upvotes: 2

T.J. Crowder
T.J. Crowder

Reputation: 1075587

Is it not suppose to wait till the synchronized object gets unlocked?

The lock is held by the thread, so the fact that you're synchronizing on it twice (in the case of the first call to doSomething in main) doesn't matter, it's on the same thread. If another thread then tried to enter a synchronized block on objToSync, that other thread would wait until this thread released all of its locks.

Your code will do this:

  1. Enter main
  2. Get a lock for the current thread on the objToSync object
  3. Output "something one"
  4. Call doSomething
  5. Get a second lock for the current thread on objToSync
  6. Output "something two"
  7. Release the second lock for the current thread on objToSync
  8. Return from doSomething
  9. Output "something three"
  10. Release the first lock for the current thread on objToSync
  11. Call doSomething
  12. Acquire a new lock (for that same thread) on objToSync
  13. Output "something two"
  14. Release that lock
  15. Return from doSomething
  16. Return from main

Here's an example using two threads:

public class SyncExample {

    private static Object objToSync = new Object();

    public static final void main(String[] args) {
        Thread second;

        System.out.println("Main thread acquiring lock");
        synchronized (objToSync) {
            System.out.println("Main thread has lock, spawning second thread");
            second = new Thread(new MyRunnable());
            second.start();
            System.out.println("Main thread has started second thread, sleeping a moment");
            try {
                Thread.currentThread().sleep(250);
            }
            catch (Exception e) {
            }
            System.out.println("Main thread releasing lock");
        }
        System.out.println("Main thread sleeping again");
        try {
            Thread.currentThread().sleep(250);
        }
        catch (Exception e) {
        }
        System.out.println("Main thread waiting for second thread to complete");
        try {
            second.join();
        }
        catch (Exception e) {
        }
        System.out.println("Main thread exiting");
    }

    static class MyRunnable implements Runnable {

        public void run() {
            System.out.println("Second thread running, acquiring lock");
            synchronized (objToSync) {
                System.out.println("Second thread has lock, sleeping a moment");
                try {
                    Thread.currentThread().sleep(250);
                }
                catch (Exception e) {
                }
                System.out.println("Second thread releasing lock");
            }
            System.out.println("Second thread is done");
        }
    }
}

Output:

Main thread acquiring lock
Main thread has lock, spawning second thread
Main thread has started second thread, sleeping a moment
Second thread running, acquiring lock
Main thread releasing lock
Main thread sleeping again
Second thread has lock, sleeping a moment
Main thread waiting for second thread to complete
Second thread releasing lock
Second thread is done
Main thread exiting

Upvotes: 11

Pshemo
Pshemo

Reputation: 124275

Locks are reentrant so if some thread posses lock it can enter other synchronized blocks based on that lock. In your case you have only one thread (main) and he is doing something like this

synchronized(objToSync){
    System.out.println("something one");                    
    synchronized(objToSync){
        System.out.println("something two");
    }
    System.out.println("something three");
}

Upvotes: 5

Dhruv Gairola
Dhruv Gairola

Reputation: 9182

Thats because your program has only 1 thread- the main thread.

Upvotes: 1

Related Questions