...
Remove the default permission java.lang.RuntimePermission
stopThread
from the security policy file to deny the Thread.stop()
invoking code, the required privileges.
Noncompliant Code Example (blocking IO, volatile flag)
This noncompliant code example uses the advice suggested in the previous compliant solutiona volatile done
flag to indicate when the thread should shut down, as suggested above. However, this does not help in terminating the thread because it is blocked on some network IO as a consequence of using the readLine()
method.
Code Block | ||
---|---|---|
| ||
class StopSocket extendsimplements ThreadRunnable { private Socket ssocket; private volatile boolean done = false; public void runshutdown() { done = true; } while (!done public void run() { try { socket = s = newnew Socket("somehost", 25); BufferedReader br = new BufferedReader(new InputStreamReader(ssocket.getInputStream())); String sstring = null; while (!done while&& ((sstring = br.readLine()) != null) { // Blocks until end of stream (null) } } catch (IOException ie) { // Forward to handler } } finally { public static void main(String[] args) throws doneIOException, =InterruptedException true;{ StopSocket }ss = new StopSocket(); } Thread thread }= new Thread(ss); public void shutdownthread.start(); throws IOException { Thread.sleep(1000); done = truess.shutdown(); } } class Controller { public static void main(String[] args) throws InterruptedException, IOException { Thread thread = new Thread(new Container()); t.start(); Thread.sleep(1000); ss.shutdown(); } } |
A Socket
connection is not affected by the InterruptedException
that results with the use of the Thread.interrupt()
method. The boolean
flag solution does not work in such cases.
Compliant Solution (close socket connection)
This compliant solution closes the socket connection, both using the shutdown()
method as well as the finally
block. As a result, the thread is bound to stop due to a SocketException
. Note that there is no way to keep the connection alive if the thread is to be cleanly halted immediately.
Noncompliant Code Example (blocking IO, interruptible)
This noncompliant code example uses thread interruption to indicate when the thread should shut down, as suggested above. However, this does not help in terminating the thread because it is blocked on some network IO as a consequence of using the readLine()
method. Network I/O is not responsive to thread interruption.
Code Block | ||
---|---|---|
| ||
class StopSocket implements Runnable {
private Socket socket;
public void run() {
try {
socket = new Socket("somehost", 25);
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String string = null;
while (!Thread.interrupted() && (string = br.readLine()) != null) {
// Blocks until end of stream (null)
}
} catch (IOException ie) {
// Forward to handler
}
}
public static void main(String[] args) throws IOException, InterruptedException {
StopSocket ss = new StopSocket();
Thread thread = new Thread(ss);
thread.start();
Thread.sleep(1000);
thread.interrupt();
}
}
|
Compliant Solution (close socket connection)
This compliant solution closes the socket connection, by having the shutdown()
method close the socket. As a result, the thread is bound to stop due to a SocketException
. Note that there is no way to keep the connection alive if the thread is to be cleanly halted immediately.
Code Block | ||
---|---|---|
| ||
class StopSocket implements Runnable {
private Socket socket;
public void shutdown() throws IOException {
if (socket != null) {
socket.close();
}
}
| ||
Code Block | ||
| ||
class StopSocket extends Thread { private Socket s; public void run() { try { ssocket = new Socket("somehost", 25); BufferedReader br = new BufferedReader(new InputStreamReader(ssocket.getInputStream())); String sstring = null; while ((sstring = br.readLine()) != null) { // Blocks until end of stream (null) } } catch (IOException ie) { // HandleForward theto exception handler } finally { try { if(s != null) s.closeshutdown(); } catch (IOException e) { /* Forward to handler */ } } } public// voidHandle shutdown()the throwsexception IOException { if(s != null) s.close(); } } } class Controller { public static void main(String[] args) throws InterruptedExceptionIOException, IOExceptionInterruptedException { StopSocket ss = new StopSocket(); Thread tthread = new Thread(ss); tthread.start(); Thread.sleep(1000); ss.shutdown(); } } |
...
Code Block | ||
---|---|---|
| ||
class StopSocket extendsimplements ThreadRunnable { private volatile boolean done = false; public void run() { while (!doneThread.interrupted()) { try { InetSocketAddress addr = new InetSocketAddress("somehost", 25); SocketChannel sc = SocketChannel.open(addr); ByteBuffer buf = ByteBuffer.allocate(1024); sc.read(buf); // ... } catch (IOException ie) { // Handle the exception } } finally {} public static void main(String[] args) throws IOException, InterruptedException done{ = true; StopSocket ss = new }StopSocket(); } Thread thread }= new Thread(ss); public void shutdownthread.start() throws; IOException { Thread.sleep(1000); done = truethread.interrupt(); } } |
This method interrupts the current thread, however, it only stops the thread because the thread logic polls the interrupted flag using the method Thread.interrupted()
, and shuts down when it is interrupted.
Risk Assessment
Trying to force thread shutdown can result in inconsistent object state and corrupt the object. Critical resources may also leak if cleanup operations are not carried out as required.
...