Thanks for explaining this. Your examples make it very clear. When I am done with "Effective Java" I plan to pick up one of the threads books (both seem to be equally well-recommended). I understand the basic "idea" of threads, but it's tips like this (using synchronized blocks instead of synchronizing the entire method, for performance) that I don't know much about.
Erik
Mike Jackson wrote:
Hmm, I wish I'd been paying attention to the list, but basically yes. You get finer control by using synchronized code blocks. Really the major reason is that you in most cases don't really need to synchronize the entire method, only small portions of the code. For example:protected static Object lock = new Object(); protected static int nextId = 1; public int getNextId() { int id = -1; synchronized( lock ) { id = nextId; nextId++; } return id; } public void setNextId( int i ) { synchronized( lock ) { nextId = i; } } As you can see we've got protection for the variable we care about, namely "nextId". And we've got it setup such that you can have threads accessing nextId both in the getNext and setNext methods. Now you're probably saying that you could use the synchronized statement on the methods here. The answer to that is nope, when you synchronize the method you're synchronizing on "this", since the goal is to protect a static variable you're not going to want to do that. Now even if the nextId wasn't static, you have to consider that you might be doing other work in the methods. Work that doesn't need to be synchronized. For example we might have something like this: protected int id = 1; public synchronized void spin( int i ) /* start crit section */ int i, max = id; id++; /* end crit section */ for ( int i = 0; i < max; i++ ) { ; } } Ok, so this code is safe, but is it efficent? We're blocking threads from entering which will protect the "id" variable, but we'll be taking time outside the crit section which will also be protected. Clearly we don't really want to do this. A better way to do this is: protected Object lock = new Object(); protected int id = 1; public synchronized void spin( int i ) int i, max; /* start crit section */ synchronized( lock ) { max = id; id++; } /* end crit section */ for ( int i = 0; i < max; i++ ) { ; } } We're still protecting the crit section, but we aren't impeding other threads from entering and even completing their pass through the method prior to our finish. However sucky examples and all making code thread safe is a lot of work. There's some "recipes" out there for generating thread safe code, but quite frankly I don't remember them any more. But there's some really good books that we mentioned by other people, the addison westley book is good, and the o'reilly threads book is good. --mikej -=----- mike jackson [EMAIL PROTECTED]-----Original Message----- From: Erik Price [mailto:[EMAIL PROTECTED]] Sent: Wednesday, January 29, 2003 12:26 PM To: Tomcat Users List Subject: Re: about singletons (ot) So you mean that the original author (mike jackson) was saying that he used synchronized code blocks to apply a finer level of detail in specifying what is synchronized and what isn't, as opposed to just declaring an entire method synchronized? I understand that synchronization implies a performance penalty, but I wasn't sure what the advantage to using synchronized blocks over synchronized methods was. Erik Tobias Dittrich wrote:The reason why you don't want to use synchronized methods is that a synchronized block can only be executed by one thread at atime. Every otherthread wanting to access this method will be blocked duringthis time (well,basically). So you want to try to keep the synchonized blocksas small aspossible. Having said that I wonder weather performance is an issue inthe singletonvs only-static discussion. Is there a significant difference inexecutionspeed? After all one has to make one additional method callevery time whenaccessing a singleton method (the getInstance() which is synchronized, too). And since we're off topic anyway: is a call to a staticmethod fasterthan a "normal" one to an object (well, I mean the overheadfrom the methodcall, not the execution speed of the method body ... )? Cheers Tobi From: "Erik Price" <[EMAIL PROTECTED]> To: "Tomcat Users List" <[EMAIL PROTECTED]> Sent: Wednesday, January 29, 2003 1:46 PM Subject: Re: about singletons (ot)Mike Jackson wrote:The difference is that if you use a singleton there's one instance. If everything is static then you only have one copy. Usually when you use asingletonit's to control access to some resource, the intent is that you use thesingletonand some synchronized calls (note I don't mean synchronized methods, butsynchronizedcode blocks) to control threads using that resource.Why could you not use synchronized methods? Erik--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]