Java Reference
In-Depth Information
key . channel (). close ();
}
catch ( IOException cex ) {}
}
}
}
}
}
This example only uses one thread. There are situations where you might still want to
use multiple threads, especially if different operations have different priorities. For in‐
stance, you might want to accept new connections in one high-priority thread and
service existing connections in a lower-priority thread. However, you're no longer re‐
quired to have a 1:1 ratio between threads and connections, which improves the scala‐
bility of servers written in Java.
It may also be important to use multiple threads for maximum performance. Multiple
threads allow the server to take advantage of multiple CPUs. Even with a single CPU,
it's often a good idea to separate the accepting thread from the processing threads. The
thread pools discussed in Chapter 3 are still relevant even with the new I/O model. The
thread that accepts the connections can add the connections it's accepted into the queue
for processing by the threads in the pool. This is still faster than doing the same thing
without selectors because select() ensures you're never wasting any time on connec‐
tions that aren't ready to receive data. On the other hand, the synchronization issues
here are tricky, so don't attempt this until profiling proves there is a bottleneck.
Buffers
In Chapter 2 , I recommended that you always buffer your streams. Almost nothing has
a greater impact on the performance of network programs than a big enough buffer. In
the new I/O model, you're no longer given the choice. All I/O is buffered. Indeed, the
buffers are fundamental parts of the API. Instead of writing data onto output streams
and reading data from input streams, you read and write data from buffers. Buffers may
appear to be just an array of bytes as in buffered streams. However, native implemen‐
tations can connect them directly to hardware or memory or use other, very efficient
implementations.
From a programming perspective, the key difference between streams and channels is
that streams are byte-based whereas channels are block-based. A stream is designed to
provide one byte after the other, in order. Arrays of bytes can be passed for performance.
However, the basic notion is to pass data one byte at a time. By contrast, a channel passes
blocks of data around in buffers. Before bytes can be read from or written to a channel,
the bytes have to be stored in a buffer, and the data is written or read one buffer at a
time.
Search WWH ::




Custom Search