Java 1.5 Tiger A Developers Notebook [Electronic resources]

David Flanagan, Brett McLaughlin

نسخه متنی -صفحه : 131/ 99
نمايش فراداده

10.6 Using Executor as a Service

While Executor on its own is a great addition to Java, there are times when you need more control over how execution occurs, when it stops, and even how it stops. For all of these cases, ExecutorService should be used.

10.6.1 How do I do that?

If you take a close look at the factory method signatures for Executors, you'll note that each returns an ExecutorService, rather than an Executor. java.util.concurrent.ExecutorService is a subinterface of Executor, and adds a good deal of functionality to the simple execute( ) method you saw in "Separating Thread Logic From Execution." Two of these are key in allowing you to stop an ExecutorService, either for an error condition or in a normal shutdown situation:

NOTE

This isn't a fully (or even partially) functional FTP server, and is just used for example purposes. You won't find it in the sample code, as it doesn't actually work.

public class FtpServer {
private ExecutorService service;
public FtpServer(int port) throws IOException {
openSocket(port);
service = Executors.newFixedThreadPool(100);
}
public void go( ) {
try {
while (true) {
service.execute(new FtpHandler(getSocket( )));
}
} catch (Exception e) {
service.shutdownNow( );
}
}
public void stop( ) {
try {
service.shutdown( );
} catch (Exception e) {
// report problem
}
}  
}
class FtpHandler implements Runnable {
private Socket socket;
public FtpHandler(Socket socket) {
this.socket = socket;
}
public void run( ) {
// Handle connection
}
}

NOTE

Basically, getSocket( ) would wait for a client to connect, and return the connection to that client as a Socket object.

This little pseudo-class primarily illustrates two methods:

shutdown( )

This method stop the service, but first allows the service to attempt to complete all running and queued tasks. No new tasks are accepted after this call, though.

shutdownNow( )

A little more direct, this method stops the service, and does not allow any queued or running tasks to execute. Currently running tasks are basically tossed, and queued tasks are returned via a List<Runnable>, for program use (if desiredin the example, I ignored these completely).

You can choose whichever of these suits you, based on your application needs. There's one other big advantage of using ExecutorService, which the next lab, Using Callable Objects, looks at in detail.