...
Code Block |
---|
|
class StopSocketSocketReader implements Runnable {
private final Socket socket;
private final BufferedReader in;
private final Object lock = new Object();
private volatile boolean done = false;
public StopSocketSocketReader() 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 {
synchronized (lock) {
while (!done && (string = in.readLine()) != null) {
// Blocks until end of stream (null)
}
}
} catch (IOException ie) {
// Forward to handler
}
}
public void shutdown() {
done = true;
}
public static void main(String[] args) throws IOException, InterruptedException {
StopSocketSocketReader ssreader = new StopSocketSocketReader();
Thread thread = new Thread(ssreader);
thread.start();
Thread.sleep(1000);
ssreader.shutdown();
}
}
|
Noncompliant Code Example (blocking IO, interruptible)
...
Code Block |
---|
|
class StopSocketSocketReader implements Runnable {
// ...
public void run() {
String string;
try {
synchronized (lock) {
while (!Thread.interrupted() && (string = in.readLine()) != null) {
// Blocks until end of stream (null)
}
}
} catch (IOException ie) {
// Forward to handler
}
}
public static void main(String[] args) throws IOException, InterruptedException {
StopSocketSocketReader ssreader = new StopSocketSocketReader();
Thread thread = new Thread(ssreader);
thread.start();
Thread.sleep(1000);
thread.interrupt();
}
}
|
...
Code Block |
---|
|
class StopSocketSocketReader 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
} finally {
try {
shutdown();
} catch (IOException e) {
// Forward to handler
}
}
}
public void shutdown() throws IOException {
socket.close();
}
public static void main(String[] args) throws IOException, InterruptedException {
StopSocketSocketReader ssreader = new StopSocketSocketReader();
Thread thread = new Thread(ssreader);
thread.start();
Thread.sleep(1000);
ssreader.shutdown();
}
}
|
A boolean
flag can be used (as described earlier) if additional clean-up operations need to be performed.
...
Code Block |
---|
|
class StopSocketSocketReader implements Runnable {
private final SocketChannel sc;
private final Object lock = new Object;
public StopSocketSocketReader() throws IOException {
this.sc = SocketChannel.open(new InetSocketAddress("somehost", 25));
}
public void run() {
ByteBuffer buf = ByteBuffer.allocate(1024);
try {
synchronized (this.lock) {
while (!Thread.interrupted()) {
this.sc.read(buf);
// ...
}
}
} catch (IOException ie) {
// Forward to handler
}
}
public static void main(String[] args) throws IOException, InterruptedException {
StopSocketSocketReader ssreader = new StopSocketSocketReader();
Thread thread = new Thread(ssreader);
thread.start();
Thread.sleep(1000);
thread.interrupt();
}
}
|
...