views:

212

answers:

3

I have been studying internals of Java for quite some time. I am curious to learn and understand how threading/locking takes place in Java.

So, in order to access a synchronized method or a synchronized block, the thread has to acquire the lock on the object first. So, now, here is what I need a bit more light.

So, whenever the thread acquires the lock on the object, does it increment the value of the semaphore internally? If the answer is yes then let's take a look at this scenario.

class ABC{ 

    public void method_1(){
        synchronized(xyz){
            ....
        }
    }

    public void method_2(){
        ...
        synchronized(xyz){
            ....
        }
    }
}

So, say there are two threads: Threaad 1 and Thread 2. Assuming, Thread1 entered method_1 first and therefore acquired a lock on xyz first. And, say now, Thread2 enters method_2 and tries to acquire lock on xyz. What will happen? (Acc to me, Thread2 will get blocked since it finds that the object's semaphore value>0)

Let me know if my reasoning is correct.

+1  A: 

whenever the thread acquires the lock on the object, does it increment the value of the semaphore internally?

Implementation specific, but unlikely, Since every lock can be obtained only once, there is no need for a counter. A simple toggle will do. I assume that every lock holds a reference to the Thread that owns it (or null).

Update: Actually, it is quite a bit more complex than that. The lock also needs to maintain a list of threads that are waiting for it. Also, a thread can temporarily release a lock via the wait/notify mechanism (so there will be an entry counter after all). On top of that, lock management has a big impact on performance, so that there are all kinds of optimizations going on. I found this interesting blog by someone who is working on JVM locking.

So, say there are two threads: Threaad 1 and Thread 2. Assuming, Thread1 entered method_1 first and therefore acquired a lock on xyz first. And, say now, Thread2 enters method_2 and tries to acquire lock on xyz. What will happen?

Yes, Thread 2 will be blocked, and wait until it can eventually obtain the lock.

Thilo
+1  A: 

Your reasoning is roughly correct. Thread 2 will be blocked, and will remain blocked until (at least) Thread1 releases the mutex.

However, the lock is generally not implemented using a conventional semaphore with a simple counter. Typically there is a single lock bit that only gets "inflated" into a full lock if the object is locked reentrantly (e.g. if Thread1 tries to lock xyz while it already holds the lock on that object) or when there is contention for the lock (e.g. when Thread2 tries to lock xyz while Thread1 has it locked).

But you don't need to concern yourself with the implementation details of Java locks ... unless you are implementing a JVM yourself!

Stephen C
+1  A: 

The other answers have pretty much answered your question, but for further reading I recommend: Java Concurrency In Practice

edwardTheGreat