When building strings within a tight loop, use string buffers instead of
string concatenation to build the strings.
For synchronization, pick a strategy and stick with it.
Synchronization carries overhead. Use it where it is necessary, but never
add synchronized to all of the methods just to be safe. Some standards
prefer synchronization on a method level where possible. Others recom-
mend locking specific objects for greater control.
Know how Java handles synchronization. Two misconceptions are com-
mon. The first is that a synchronized section protects a block of code. It
doesn't; it only protects code for the threads executing in one instance
since all locks are on the object level. The second misconception is that
atomic functions do not need protection. In truth, only very small byte
movements are considered atomic.
Where possible, try to avoid blocking. For files, use the nonblocking IO
package java.nio (beginning in Java 1.4).
When a response is not required immediately, use a queue instead of a
transaction or RPC .
Wherever possible, spin off threads to handle tasks that are likely to
Some applications require shared access for readers and exclusive access
for writers. In these circumstances, use read / write locks (see the antipat-
tern description in “Synchronized read / write bottleneck,” in chapter 5)
to limit the amount of blocking.
Conventions for testing
Still underwater on the Pine Creek rapid, I go through a mental checklist to
make sure that my paddle, head, knuckles, and back are in the correct position.
After 8 seconds that feel like an eternity, I sense my life jacket's buoyancy bringing
my right side near the surface, giving me an opening to roll. I sweep out my pad-
dle, snap my hips, brace with the paddle, and shoot upright. Feeling relieved, I
position my kayak and resume the run.
I mention this story because we now go from a valued and respected topic to
one that is … not. I hate practicing rolls and getting water up my nose, but