This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
As I understand it my code is thread-safe in the sense that a single instance of UIDFactory will not create duplicate IDs nor will the static methods create duplicate IDs. I don't care if different instances of UIDFactory can create duplicate IDs nor do I care if an instance might duplicate an ID generated by the static methods, they're intended to be seperate. Using a method that's not synchronized is still okay since it calls a method that is synchronized to generate the actual ID isn't it? Can someone validate my understanding here? Thanks. [ October 12, 2005: Message edited by: Ken Blair ]
Originally posted by Ken Blair: Using a method that's not synchronized is still okay since it calls a method that is synchronized to generate the actual ID isn't it?
That' how I understand this too --- in particular since the unsynchronized method does not otherwise mess with the instance variables.
Joined: Jul 15, 2003
I noticed a flaw in it today. At the time I didn't realize what exactly a synchronized keyword did with methods. I've since changed the static methods to use synchronized blocks on TIMEMS and ORDINAL to lock those and removed the keyword from the method entierely. Having a synchronized static method locks the entire Class which was undesirable as there's no reason for getUIDAsString() to prevent getNextUID()/getNextUIDAsString which are instance methods and use different variables. Unfortunately I had to give up lazy instantiation to do it, but that was more important. It now looks more like this:
This is the proper way to do it right? I need to lock TIMEMS and ORDINAL to make sure they don't get manipulated by two threads at the same time.
It was better before. You cant synchronize on an int anyway so that won't compile. A synchronized method only stops entry into other synchronized methods that use the same monitor; it does not effect entry into unsynchronized methods. It also does not stop entry into other synchronized methods that synchronize on a different monitor.
If by chance you are using java 1.5 and that did compile, then we have a new type of mistake to be aleart of in 1.5. autoboxing allowing you to synchronize. without knowing 1.5 i can still safely say never synchronize on an autoboxed variable.
if it were my i would do the following
in other words, there was no flaw. Note: You don't lock objects. You use objects (by using its monitor) to lock blocks of code.
Joined: Jul 15, 2003
Originally posted by Mr. C Lamont Gilbert: You cant synchronize on an int anyway so that won't compile.
I changed int to Integer. I figured anyone reading would assume that, sorry for the confusion. Would there be anything wrong with using an Integer?
Originally posted by Mr. C Lamont Gilbert: It was better before. A synchronized method only stops entry into other synchronized methods that use the same monitor; it does not effect entry into unsynchronized methods. It also does not stop entry into other synchronized methods that synchronize on a different monitor.
I disagree with your statement that it's better. I don't dispute anything else in that paragraph, but I also don't see the point. It doesn't stop unsychronized methods, but the only unsynchronized method of relevence calls a synchronized method to do the work.
Does a synchronized static method not lock the monitor on the entire Class? As far as I'm aware, a synchronized static method will block all synchronized methods of the same Class including both static and normal instance methods. That means if a thread called getUID() or getUIDAsString() no other methods could be called (or at least not return) until it was finished. Yes, getUID() and getNextUID() could be called but they couldn't ever return until the lock was given up since they depend on the synchronized methods getUIDAsString() and getNextAsString().
Originally posted by Mr. C Lamont Gilbert:
This introduces a new concept to me of using the monitor of an Object we don't really care about to restrict access to critical sections. That being said, it seems silly in this case. I can just use TIMEMS instead. Why not? You only lose lazy instantiation which is no gain to begin with since you're having to create the other Object. Wouldn't this be optimal:
You made me realize I don't need a lock on ORDINAL because all the code that accesses ORDINAL and TIMEMS will logically need a lock on TIMEMS. I just have to be sure that in the future developers know to never make those accessible to the public and to always lock on TIMEMS if they add in methods that modify ORDINAL or TIMEMS. Am I wrong? [ October 14, 2005: Message edited by: Ken Blair ]