>>,although Java makes threading relatively easy... <pun type="bad"> I find Java gives you more than enough thread to hang yourself with ;-> </pun>
-----Original Message----- From: David Graham [mailto:[EMAIL PROTECTED]] Sent: Tuesday, 28 January 2003 23:14 To: [EMAIL PROTECTED] Subject: Re: Synchronized blocks? Thanks for the explanation Craig. That's what I meant when I said that unsynchronized methods can be called regardless of synchronized method calls. And of course you can't fully tell if a class is thread safe by the existence of synch. methods. I was concerned when I saw unsynch. access to member variables and wanted to confirm my understanding of thread safety. IMHO, although Java makes threading relatively easy, it's still a bit tricky. Thanks, Dave >From: "Craig R. McClanahan" <[EMAIL PROTECTED]> >Reply-To: "Struts Developers List" <[EMAIL PROTECTED]> >To: Struts Developers List <[EMAIL PROTECTED]> >Subject: Re: Synchronized blocks? >Date: Mon, 27 Jan 2003 22:28:56 -0800 (PST) > > > >On Mon, 27 Jan 2003, David Graham wrote: > > > Maybe I'm displaying gross ignorance here but AFAIK a synchronized block > > grabs the object's monitor and blocks other threads from calling > > *synchronized* methods on that object, right? Unsynchronized methods on > > that object can be called at will. > >To further illustrate this situation (for the record, in the archives). > >The following two approaches to synchronizing access to a local variable >have *exactly* the same effect: > > public class Foo { > > private Map bar = new HashMap(); > > public synchronized void modifyBar() { > ... do something that accesses bar ... > } > > public differentMethod() { > ... do something else ... > } > > } > > > public class Foo { > > private Map bar = new HashMap(); > > public void modifyBar() { > synchronized (this) { > ... do something that accesses bar ... > } > } > > public differentMethod() { > ... do something else ... > } > > } > >Note that *neither* approach causes calls to differentMethod() to be >blocked, so if differentMethod() also accesses bar, then you're in >trouble. > >In that sort of scenario, I prefer to explicitly lock the collection I'm >accessing instead, and do so for the absolute minimum amount of time. >Consider this class: > > public class Foo { > > private Map bar = new HashMap(); > > private Map baz = new HashMap(); > > public void modifyBar() { > ... stuff that does NOT access bar or baz ... > synchronized (bar) { > ... do something that accesses bar ... > } > ... stuff that does NOT access bar or baz ... > } > > public differentMethod() { > ... stuff that does NOT access bar or baz ... > synchronized(bar) { > ... do something that accesses bar ... > } > ... stuff that does NOT access bar or baz ... > } > > public anotherMethod() { > ... stuff that does NOT access bar or baz... > synchronized(baz) { > ... do something that accesses baz ... > } > ... stuff that does NOT access bar or baz ... > } > > > } > >Note that this latter example locks explicitly on the "bar" or "baz" >variable, instead of on "this" (i.e. the Foo instance). Because of that, >we experience several benefits to our performance in a multithreaded >environment: > >* The "stuff that does NOT access bar or baz" chunks of code are > never blocked by a lock. > >* Calls to differentMethod() never block calls to anotherMethod(), > and vice versa. > >If you synchronized all three methods, you would indeed achieve thread >safety, but at the cost of calls to any one method blocking calls to the >other two (remember, they'd all effectively be synchronizing on "this"). > >If you used Collections.synchronizedMap() around bar and baz, you wouldn't >need synchronization blocks in the methods, but you'd cause multiple locks >to occur if there were more than one statement accessing the underlying >collection inside the blocks. > >Note also that the caller of any of these methods does not have to be >concerned about thread safety -- the Foo class takes care of protecting >itself already. In general, that is a better design philosophy than >shoving the responsibility back o the user -- except for cases (such as >HashMap) where you explicitly *want* the caller to have the opportunity to >use your class with no locks at all, such as in a single threaded batch >application. Indeed, this is why HashMap is more performant than >Hashtable -- locks are only required when you're multithreading acces to >it. But the downside is that it is *your* responsibility, not the JDK"s, >to figure out when this is needed. > >Craig > > > > >-- >To unsubscribe, e-mail: ><mailto:[EMAIL PROTECTED]> >For additional commands, e-mail: ><mailto:[EMAIL PROTECTED]> _________________________________________________________________ MSN 8 helps eliminate e-mail viruses. Get 2 months FREE*. http://join.msn.com/?page=features/virus -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]> -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>