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]>

Reply via email to