I am having following queries related to the code enclosed :
* In synchronized block of Calculator..Why we have to give "this" as a parameter..Why is it wrong if we give "c" , After all , we invoke wait on lock "c" , so as rules have to notify on lock "c" only.
* Why do we need to pass "Calculator" object in "App" objects ?
In synchronized block of Calculator..Why we have to give "this" as a parameter..Why is it wrong if we give "c" , After all , we invoke wait on lock "c" , so as rules have to notify on lock "c" only.
Because "this" in Calculator and "c" in App are the same at that point (both refer to object #1). "c" in App points to a Calculator instance, but within that Calculator instance to lock that instance you need to synchronize on the whole Calculator. Note that the Calculator c within Calculator serves no purpose and the code would still compile if it were removed. Locking/synchronizing on that c would not only fail (because locking a null object throws a null pointer exception), but if that calculator were initialized, it would be locking on a different Calculator than the one in App.
Why do we need to pass "Calculator" object in "App" objects ?
Because the Calculator defined in main is in a static method. Static methods do not require an instance of the class to execute, they are "shared" between all instances. If you didn't want to pass the Calculator to the App, you could make the Calculator at the App class level static, allowing the main method to access it. (but making it shared between all threads) Main can't access the Calculator right now because there could be many different Calculators around, one for each App instance and Java doesn't know which Calculator instance would be correct to access.
Or here's another question, what if you had no Apps. What would the Calculator field mean then? The calculator belongs to an instance of an App. The main method requires a minimum of zero App instances to be called. So the calculator doesn't make sense to be available to the main method, it wouldn't know what to do with it.
If might be clearer that the Calculator belongs to the App if you pull the main method out into a different class. Then you can see clearly what belongs where...
Now the main method is totally separate from the actual App object. It's just using the features of the object and just looking at the AppDriver class it's not clear that the App even has a Calculator field.
If the Calculator didn't belong to the App - if no matter how many Apps you had, there was still one calculator, it would make sense to access a Calculator even if there were no apps. And that is what the static keyword is for. It marks an object (method or variable) as belonging to the App class, and that it is shared between all instances. Then main could see it because neither of them require an App exist in order to work.