...
Code Block | ||
---|---|---|
| ||
class SocketReader implements Runnable { private final Socket socket; private final BufferedReader in; private finalvolatile Objectboolean lockdone = new Object()false; private volatile boolean doneisRunning = false; private class MultipleUseException extends RuntimeException {}; public SocketReader() throws IOException { this.socket = new Socket("somehost", 25); this.in = new BufferedReader(new InputStreamReader(this.socket.getInputStream())); } // Only one thread can use the socket at a particular time public void run() { String string; try { synchronizedif (lockisRunning) { whilethrow new (!done && (string = in.readLine()) != null) {MultipleUseException(); } isRunning = true; // Blocks until end of stream execute(null); } } } catch (IOException ie) { // Forward to handler } } public void shutdownexecute() throws IOException { doneString = truestring; } publicwhile static void main(String[] args) throws IOException, InterruptedException { SocketReader reader = new SocketReader();(!done && (string = in.readLine()) != null) { // Blocks until end of stream (null) Thread} thread =} new Threadpublic void shutdown(reader); { done = thread.start()true; } Thread.sleep(1000); public static void main(String[] args) throws IOException, InterruptedException { SocketReader reader.shutdown = new SocketReader(); } Thread thread = new Thread(reader); thread.start(); Thread.sleep(1000); reader.shutdown(); } } |
Noncompliant Code Example (blocking IO, interruptible)
...
Code Block | ||
---|---|---|
| ||
class SocketReader implements Runnable { // ... public void runexecute() throws IOException { String string; try { synchronized (lock) { while (while (!Thread.interrupted() && (string = in.readLine()) != null) { // Blocks until end of stream (null) } } public static } } catch (IOException ie) { void main(String[] args) throws IOException, InterruptedException { SocketReader // Forward to handler } } public static void main(String[] args) throws IOException, InterruptedException { SocketReader reader = reader = new SocketReader(); Thread thread = new Thread(reader); thread.start(); Thread.sleep(1000); thread.interrupt(); } } |
...
Code Block | ||
---|---|---|
| ||
class SocketReader implements Runnable { // ... public void run() { String string; try { synchronized (lock) { while ((string = in.readLine()) != null) { // Blocks until end of stream (null) } } } catch (IOException ie) { // Forward to handler public void execute() throws IOException { String string; try { } finally { while ((string = in.readLine()) != null) try{ { shutdown(); } catch (IOException e) { // Blocks until end of stream (null) } // Forward} tofinally handler{ }shutdown(); } } public void shutdown() throws IOException { socket.close(); } public static void main(String[] args) throws IOException, InterruptedException { SocketReader reader = new SocketReader(); Thread thread = new Thread(reader); thread.start(); Thread.sleep(1000); reader.shutdown(); } } |
...
Code Block | ||
---|---|---|
| ||
class SocketReader implements Runnable { private final SocketChannel scSocketChannel sc; private final Object lock = new Object; private volatile boolean isRunning = false; private finalclass ObjectMultipleUseException lockextends = new ObjectRuntimeException {}; public SocketReader() throws IOException { sc = SocketChannel.open(new InetSocketAddress("somehost", 25)); } public void run() { if (isRunning) { throw new MultipleUseException(); } isRunning = true; ByteBuffer buf = ByteBuffer.allocate(1024); try { synchronized (lock) { while (!Thread.interrupted()) { sc.read(buf); // ... } } } catch (IOException ie) { // Forward to handler } } public static void main(String[] args) throws IOException, InterruptedException { SocketReader reader = new SocketReader(); Thread thread = new Thread(reader); thread.start(); Thread.sleep(1000); thread.interrupt(); } } |
...