...
Code Block | ||
---|---|---|
| ||
public final class SocketReader implements Runnable { // Thread-safe class private final Socket socket; private final BufferedReader in; private volatile boolean done = false; private final Object lock = new Object(); public SocketReader(String host, int port) throws IOException { this.socket = new Socket(host, port); this.in = new BufferedReader(new InputStreamReader(this.socket.getInputStream())); } // Only one thread can use the socket at a particular time @Override public void run() { try { synchronized (lock) { readData(); } } catch (IOException ie) { // Forward to handler } } public void readData() throws IOException { String string; try { while ((string = in.readLine()) != null) { // Blocks until end of stream (null) } } finally { shutdown(); } } public void shutdown() throws IOException { socket.close(); } } public final class PoolService { private final ExecutorService pool; public PoolService(int poolSize) { pool = Executors.newFixedThreadPool(poolSize); } public void doSomething() throws InterruptedException, IOException { pool.submit(new SocketReader("somehost", 8080)); // ... List<Runnable> awaitingTasks = pool.shutdownNow(); } public static void main(String[] args) throws InterruptedException, IOException { PoolService service = new PoolService(5); service.doSomething(); } } public final class SocketReader implements Runnable { private final Socket socket; // ... } |
Because the task does not support interruption using Thread.interrupt()
, there is no guarantee that the shutdownNow()
method will shutdown the thread pool. Using the shutdown()
method does not fix the problem either, because it waits until all executing tasks have finished.
...
Code Block | ||
---|---|---|
| ||
public final class SocketReader implements Runnable { private final SocketChannel sc; private final Object lock = new Object(); public SocketReader(String host, int port) throws IOException { sc = SocketChannel.open(new InetSocketAddress(host, port)); } @Override public void run() { ByteBuffer buf = ByteBuffer.allocate(1024); try { synchronized (lock) { while (!Thread.interrupted()) { sc.read(buf); // ... } } } catch (IOException ie) { // Forward to handler } } } public final class PoolService { // ... } public final class SocketReader implements Runnable { private final SocketChannel sc; // ... } |
Exceptions
CON31-EX1: Short-running tasks that execute without blocking are not required to adhere to this guideline.
...