struts-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Andrew Hill" <andrew.david.h...@gridnode.com>
Subject RE: Synchronized blocks?
Date Tue, 28 Jan 2003 15:20:17 GMT
>>,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:dgraham1980@hotmail.com]
Sent: Tuesday, 28 January 2003 23:14
To: struts-dev@jakarta.apache.org
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" <craigmcc@apache.org>
>Reply-To: "Struts Developers List" <struts-dev@jakarta.apache.org>
>To: Struts Developers List <struts-dev@jakarta.apache.org>
>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:struts-dev-unsubscribe@jakarta.apache.org>
>For additional commands, e-mail:
><mailto:struts-dev-help@jakarta.apache.org>


_________________________________________________________________
MSN 8 helps eliminate e-mail viruses. Get 2 months FREE*.
http://join.msn.com/?page=features/virus


--
To unsubscribe, e-mail:   <mailto:struts-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:struts-dev-help@jakarta.apache.org>


--
To unsubscribe, e-mail:   <mailto:struts-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:struts-dev-help@jakarta.apache.org>


Mime
View raw message