the service try { for (;;) { pool.execute(new Handler(serverSocket.accept())); } } catch (IOException ex) { pool.shutdown(); } } } class Handler implements Runnable { private final Socket socket; Handler(Socket socket) { this.socket = socket; } public void run() { // read and service request on socket } }} The following method shuts down an {@code ExecutorService} in two phases,first by calling {@code shutdown} to reject incoming tasks, and thencalling {@code shutdownNow}, if necessary, to cancel any lingering tasks:
{@code}void shutdownAndAwaitTermination(ExecutorService pool) pool.shutdown(); // Disable new tasks from being submitted try { // Wait a while for existing tasks to terminate if (!pool.awaitTermination(60, TimeUnit.SECONDS)) { pool.shutdownNow(); // Cancel currently executing tasks // Wait a while for tasks to respond to being cancelled if (!pool.awaitTermination(60, TimeUnit.SECONDS)) System.err.println("Pool did not terminate"); } } catch (InterruptedException ie) { // (Re-)Cancel if current thread also interrupted pool.shutdownNow(); // Preserve interrupt status Thread.currentThread().interrupt(); } }}
Memory consistency effects: Actions in a thread prior to the submission of a {@code Runnable} or {@code Callable} task to an{@code ExecutorService}happen-before any actions taken by that task, which in turn happen-before the result is retrieved via {@code Future.get()}.
@since 1.5
@author Doug Lea