Remember that synchronization is based on objects -- and not references. So, changing the reference to another object means that the same code can run in parallel, as it is two different objects. It also means that previous calls to the wait() method won't get the notification, because it too, is using a different object.
Cheo Gomez wrote:the main thread has the lock of SA?
does the wait method gets called?
the run method is executed in this code?
As already mentioned, the code is broken, so the example is really moot. However, if you want possible examples of what happens, here are a few possibilities.
1. If the t1 thread gets to lock SA, before the main thread changes it to "Done" -- meaning locks the "Not Done" object. It will then call wait(), hence release the lock on the "Not Done" object. Later, the main thread locks the "Not Done" object, changes it "Done", and sends the notification on the "Done" object. Unfortunately, the other thread is waiting on the "Not Done" object, and hence, doesn't get the notification.
2. If the main thread gets to lock SA first, meaning locks the "Not Done" object. It will change it the "Done" object. And send the notification. Later, the t1 thread, may either lock the "Not Done" or the "Done" object, depending whether the main thread changed it at the time the t1 thread reaches the synch block. It really doesn't matter which object it locks, as in both cases, it will see "Done" (in the "if" condition), and *not* call the wait() method.
[EDIT] -- Oops, just realized the sa reference for the main thread is not the same sa reference as the t1 thread. The t1 thread always see the "Not Done" object. It will wait on the "Not Done" object. And never see the "Done" object or the notification sent on it.
Cheo Gomez wrote:Hi comunity, I have a doubth with this question, I dont understand, when they made the call to syncronized(sa) in the main method, what object they are sincronizing?
The idea that we "synchronize an object" is incorrect.
Rather, we synchronize on an object, which means only that we obtain that object's lock.
Syncing works like so:
Every object has an inherent "lock". Whenever we do synchronized(X), what that means is that we want to grab the lock for the object that X points to, and that we'll stop there and wait until that lock is released if some other thread currently holds it. That's all that syncing does*. Everything else is built on top of that.
*It also ensures that the current thread's local copies of shared variables are copied to and from main memory, but that part isn't relevant to the mutual exclusion and atomicity stuff we're talking about here.