...
This noncompliant code example demonstrates the Thread-Per-Message design that fails to provide graceful degradation of service. The class RequestHandler
provides a public static factory method so that callers can obtain an instance. Subsequently, the handleRequest()
method can be used to handle each request in its own thread.
Code Block |
---|
|
class Helper {
public void handle(Socket socket) {
//...
}
}
final class RequestHandler {
private final Helper h = new Helper();
private static ServerSocket server;
private RequestHandler(int port) throws IOException {
server = new ServerSocket(port);
}
public static RequestHandler getInstance(int port) throws IOException {
return new RequestHandler(port);
}
public void handleRequest() {
new Thread(new Runnable() {
public void run() {
try {
h.handle(server.accept());
} catch (IOException e) {
// Forward to handler
}
}
}).start();
}
}
|
...
Wiki Markup |
---|
This compliant solution uses a _Fixed Thread Pool_ that places an upper bound on the number of simultaneouslyconcurrently executing threads. Tasks submitted to the pool are stored in an internal queue. This prevents the system from gettingbeing overwhelmed when trying to respond to all incoming requests and allows it to degrade gracefully by serving a fixed number of clients at a particular time. \[[Tutorials 08|AA. Java References#Tutorials 08]\] |
Code Block |
---|
|
// class Helper remains unchanged
final class RequestHandler {
private final Helper h = new Helper();
private static ServerSocket server;
private static ExecutorService exec;
private RequestHandler(int port, int poolSize) throws IOException {
server = new ServerSocket(port);
exec = Executors.newFixedThreadPool(poolSize);
}
public static RequestHandler getInstance(int port, int poolSize) throws IOException {
return new RequestHandler(port, poolSize);
}
public void handleRequest() {
exec.submit(new Runnable() {
public void run() {
try {
h.handle(server.accept());
} catch (IOException e) {
// Forward to handler
}
}
});
}
}
|
...