With synchronization keyword what actually gets locked? For example, If I have following two classes:
and class testClass:
then why ownCounter.synchronized_print -method doesn't work as I expected (eg like with the mutex-block)? Instead it doesn't matter whether I call ownCounter.print or ownCounter.synchronized_print (they both give print-outs of 1-10 in random order). What actually gets locked with synchronization keyword? And how about if method is declared static? I have made another test class which interacted with database. (with concurrent issues) and it seemed to me that when method was declared static, only one thread could access it. Any help would be greatly appreciated.
The synchronized keyword locks on an Object (unless it is static). So for each object of ownCounter only 1 thread can access the synchronized_print method. Since you create 3 objects (each time they enter the run method) then each thread uses it's own object and so can access the synchronized method with no problem (each one see his own object with his own method).
The static block you use locks on a String literal (in which there is only 1) so it works as expected (try it with new String() and see that it won't work there either).
In order to work correctly you need only 1 ownCounter object (create it as a static class member). You can also declare the synchronized_print as static... [ January 22, 2006: Message edited by: Roy Ben Ami ]
AFAIK nothing actually gets locked, it's just an object's monitor is "acquired" which, once again AFAIK, is nothing more than a boolean flag. When the synchronized keyword is used in a non-static method declaration it acquires the monitor for the instance it is invoked on. When used in a static method declaration it acquires the monitor for that object's Class instance (only one of which exists in a given ClassLoader). When used in any other context i.e. synchronized (something) it acquires the monitor for "something".
[Roy]: The synchronized keyword locks on an Object (unless it is static).
I guess you mean, unless we're talking about a static synchronized method? Even then it locks an Object - specifically, an instance of the class Class, which extends Object just like every other class does.
[Ken]: AFAIK nothing actually gets locked
Yeah, this comes down to choice of terminology. The word "lock" is frequently used in this context, and to the extent that it's been defined to have a specific meaning when talking about threads, that's OK. However I think it's misleading word to use. Object "locking" is like having a house where you've locked the front door, but there's a huge obvious hole in the wall. If people who come to the house respect the protocol of knocking on the front door an waiting for someone to open it, great, your house is safe. But if they ignore the protocol and go through the hole in the wall, your "locking" did no good.
In fact it's worse than that with object locking, because the "hole" is actually the standard way we access objects, by calling them without using synchronization. Frequently people won't even realize they were supposed to use syncronization there. Or maybe there are multiple objects that might be synchronized on, and they choose the wrong one. It's like having multiple doors to a house, and you lock one door, but the others are open. (And locking all the doors has a good chance of leading to deadlock.) The challenge then is to write classes so that all the synchronization you need is within the methods of that class, and clients of the class can hopefully just use the methods without having to think about synchronization.
Note: Roy & Ken probably both know this stuff; I'm expanding on their points for the benefit of others who read this.