Hey Mike,

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 a
time. Every other

thread wanting to access this method will be blocked during
this time (well,

basically). So you want to try to keep the synchonized blocks
as small as

possible.

Having said that I wonder weather performance is an issue in
the singleton

vs only-static discussion. Is there a significant difference in
execution

speed? After all one has to make one additional method call
every time when

accessing a singleton method (the getInstance() which is  synchronized,
too). And since we're off topic anyway: is a call to a static
method faster

than a "normal" one to an object (well, I mean the overhead
from the method

call, 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 a
singleton

it's to
control access to some resource, the intent is that you use the
singleton


and some
synchronized calls (note I don't mean synchronized methods, but
synchronized


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

Reply via email to