...
This noncompliant code example shows a thread that fills a vector with pseudo-random pseudorandom numbers. The thread is stopped after a fixed amount of time.
Code Block |
---|
|
public class Container implements Runnable {
private final Vector<Integer> vector = new Vector<Integer>();
private final int numberOfTimes = 10;
public Vector<Integer> getVector() {
return vector;
}
public synchronized void run() {
Random number = new Random(123L);
for(int i = 010;
i < numberOfTimes;while i++(i > 0) {
vector.add(number.nextInt(100));
i--;
}
}
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new Container());
thread.start();
Thread.sleep(5000);
thread.stop();
}
}
|
...
Wiki Markup |
---|
However, the {{Thread.stop()}} method causes the thread to stop what it is doing and throw a {{ThreadDeath}} exception, and release all locks that it has acquired \[[API 06|AA. Java References#API 06]\]. If the thread is in the process of adding a new stringinteger to the vector when it is stopped, the vector may become accessible while it is in an inconsistent state. For instanceexample, {{Vector.size()}} may be three while the vector only contains two elements. |
...
This compliant solution stops the thread by using a volatile
flag. An accessor method shutdown()
is used to set the flag to true
, after which the thread can start the cancellation process. The thread's run()
method polls the done
flag, and shuts down when it becomes true
.
Code Block |
---|
|
public class Container implements Runnable {
private final Vector<Integer> vector = new Vector<Integer>();
private final int numberOfTimes = 10;
private volatile boolean done = false;
public Vector<Integer> getVector() {
return vector;
}
public void shutdown() {
done = true;
}
public synchronized void run() {
int i = numberOfTimes;
Random number = new Random(123L);
int i = 10;
while (!done && i > 0) {
vector.add(number.nextInt(100));
i--;
}
}
public static void main(String[] args) throws InterruptedException {
Container container = new Container();
Thread thread = new Thread(container);
thread.start();
Thread.sleep(5000);
container.shutdown();
}
}
|
...
Code Block |
---|
|
public class Container implements Runnable {
private final Vector<Integer> vector = new Vector<Integer>();
private final int numberOfTimes vector = new 10Vector<Integer>();
public Vector<Integer> getVector() {
return vector;
}
public synchronized void run() {
int i = numberOfTimes;
Random number = new Random(123L);
int i = 10;
while (!Thread.interrupted() && i > 0) {
vector.add(number.nextInt(100));
i--;
}
}
public static void main(String[] args) throws InterruptedException {
Container c = new Container();
Thread thread = new Thread(c);
thread.start();
Thread.sleep(5000);
thread.interrupt();
}
}
|
This method interrupts the current thread, however, it does not stop only stops the thread unless because the thread logic polls the interrupted flag using the method Thread.interrupted()
to stop performing any pending actions, and shuts down when it is interrupted.
Compliant Solution (RuntimePermission stopThread
)
...
Code Block |
---|
|
class StopSocket extends Thread {
private Socket s;
private volatile boolean done = false;
public void run() {
while (!done) {
try {
s = new Socket("somehost", 25);
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String s = null;
while ((s = br.readLine()) != null) {
// Blocks until end of stream (null)
}
} catch (IOException ie) {
// Forward to handler
} finally {
done = true;
}
}
}
public void shutdown() throws IOException {
done = true;
}
}
class Controller {
public static void main(String[] args) throws InterruptedException, IOException {
Thread thread = new Thread(new Container());
t.start();
Thread.sleep(1000);
ss.shutdown();
}
}
|
...
Code Block |
---|
|
class StopSocket extends Thread {
private Socket s;
public void run() {
try {
s = new Socket("somehost", 25);
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String s = null;
while ((s = br.readLine()) != null) {
// Blocks until end of stream (null)
}
} catch (IOException ie) {
// Handle the exception
} finally {
try {
if(s != null)
s.close();
} catch (IOException e) { /* Forward to handler */ }
}
}
public void shutdown() throws IOException {
if(s != null)
s.close();
}
}
class Controller {
public static void main(String[] args) throws InterruptedException, IOException {
StopSocket ss = new StopSocket();
Thread t = new Thread(ss);
t.start();
Thread.sleep(1000);
ss.shutdown();
}
}
|
...
Code Block |
---|
|
class StopSocket extends Thread {
private volatile boolean done = false;
public void run() {
while (!done) {
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 {
done = true;
}
}
}
public void shutdown() throws IOException {
done = true;
}
}
|
...