Java Reference
In-Depth Information
are CPU-bound, then the total task may finish more quickly if you can avoid a lot of
switching between threads. Finally, and most importantly, although threads help make
more efficient use of a computer's limited CPU resources, there is still only a finite
amount of resources to go around. Once you've spawned enough threads to use all the
computer's available idle time, spawning more threads just wastes MIPS and memory
on thread management.
The Executors class in java.util.concurrent makes it quite easy to set up thread
pools. You simply submit each task as a Runnable object to the pool. You get back a
Future object you can use to check on the progress of the task.
Let's look at an example. Suppose you want to gzip every file in the current directory
using a java.util.zip.GZIPOutputStream . This is a filter stream that compresses all
the data it writes.
On the one hand, this is an I/O-heavy operation because all the files have to be read and
written. On the other hand, data compression is a very CPU-intensive operation, so you
don't want too many threads running at once. This is a good opportunity to use a thread
pool. Each client thread will compress files while the main program will determine
which files to compress. In this example, the main program is likely to significantly
outpace the compressing threads because all it has to do is list the files in a directory.
Therefore, it's not out of the question to fill the pool first, then start the threads that
compress the files in the pool. However, to make this example as general as possible,
you'll allow the main program to run in parallel with the zipping threads.
Example 3-13 shows the GZipRunnable class. It has a single field that identifies the file
to compress. The run() method compresses this file and returns.
Example 3-13. The GZipRunnable class
import java.io.* ;
import java.util.zip.* ;
public class GZipRunnable implements Runnable {
private final File input ;
public GZipRunnable ( File input ) {
this . input = input ;
}
@Override
public void run () {
// don't compress an already compressed file
if (! input . getName (). endsWith ( ".gz" )) {
File output = new File ( input . getParent (), input . getName () + ".gz" );
if (! output . exists ()) { // Don't overwrite an existing file
try ( // with resources; requires Java 7
InputStream in = new BufferedInputStream ( new FileInputStream ( input ));
Search WWH ::




Custom Search