Java Reference
In-Depth Information
The code reading the logfile and adding entries to the list might look something like
this:
public void readLogFile () {
while ( true ) {
String entry = log . getNextEntry ();
if ( entry == null ) {
// There are no more entries to add to the list so
// we interrupt all threads that are still waiting.
// Otherwise, they'll wait forever.
for ( Thread thread : threads ) thread . interrupt ();
break ;
}
synchronized ( entries ) {
entries . add ( 0 , entry );
entries . notifyAll ();
}
}
}
Finish
The final way a thread can give up control of the CPU in an orderly fashion is by
finishing . When the run() method returns, the thread dies and other threads can take
over. In network applications, this tends to occur with threads that wrap a single blocking
operation, such as downloading a file from a server, so that the rest of the application
won't be blocked.
Otherwise, if your run() method is so simple that it always finishes quickly enough
without blocking, there's a very real question of whether you should spawn a thread at
all. There's a nontrivial amount of overhead for the virtual machine in setting up and
tearing down threads. If a thread is finishing in a small fraction of a second anyway,
chances are it would finish even faster if you used a simple method call rather than a
separate thread.
Thread Pools and Executors
Adding multiple threads to a program dramatically improves performance, especially
for I/O-bound programs such as most network programs. However, threads are not
without overhead of their own. Starting a thread and cleaning up after a thread that has
died takes a noticeable amount of work from the virtual machine, especially if a program
spawns hundreds of threads—not an unusual occurrence for even a low- to medium-
volume network server. Even if the threads finish quickly, this can overload the garbage
collector or other parts of the VM and hurt performance, just like allocating thousands
of any other kind of object every minute. Even more importantly, switching between
running threads carries overhead. If the threads are blocking naturally—for instance,
by waiting for data from the network—there's no real penalty to this; but if the threads
Search WWH ::




Custom Search