...
This noncompliant code example shows a thread that fills a vector with stringspseudo-random numbers. The thread is stopped after a fixed amount of time.
Code Block |
---|
|
public class Container implements Runnable {
private final Vector<String>Vector<Integer> vector = new Vector<String>Vector<Integer>();
private final BufferedReaderint innumberOfTimes = new BufferedReader(new InputStreamReader(System.in))10;
public Vector<String>Vector<Integer> getVector() {
return vector;
}
public synchronized void run() {
StringRandom stringnumber = null new Random(123L);
do {
System.out.println("Enter another string");
tryfor(int i = 0; i < numberOfTimes; i++) {
string = in.readLine(vector.add(number.nextInt(100));
} } catch (IOException
e) {}
public static void main(String[] args) // Forward to handler
}throws InterruptedException {
Thread thread = new Thread(new Container());
thread.start();
vector Thread.addsleep(string5000);
} while (!"END".equals(string))thread.stop();
}
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new Container());
thread.start();
Thread.sleep(5000);
thread.stop();
}
}
|
Because the class Vector
is thread-safe, operations performed by multiple threads on its shared instance are expected to leave it in a consistent state. For instance, the Vector.size()
method always reflects the true number of elements in the vector even when an element is added or removed. This is because the vector instance uses its own intrinsic lock to prevent other threads from accessing it while its state is temporarily inconsistent.
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 string to the vector when it is stopped, the vector may become accessible while it is in an inconsistent state. For instance, {{Vector.size()}} may be three while the vector only contains two elements. |
Compliant Solution (volatile
flag)
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.
Because the class Vector
is thread-safe, operations performed by multiple threads on its shared instance are expected to leave it in a consistent state. For instance, the Vector.size()
method always reflects the true number of elements in the vector even when an element is added or removed. This is because the vector instance uses its own intrinsic lock to prevent other threads from accessing it while its state is temporarily inconsistent.
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 string to the vector when it is stopped, the vector may become accessible while it is in an inconsistent state. For instance, {{Vector.size()}} may be three while the vector only contains two elements. |
Compliant Solution (volatile
flag)
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.
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( |
Code Block |
---|
|
public class Container implements Runnable {
private final Vector<String> vector = new Vector<String>();
private final BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
private volatile boolean done = false;
public Vector<String> getVector() {
return vector;
}
public void shutdown() {
done = true;
}
public synchronized void run() {
String string = null;
do {
System.out.println("Enter another string");
try {
string = in.readLine();
} catch (IOException e) {
// Forward to handlerreturn vector;
}
public void vector.addshutdown(string); {
} while (!done && !"END".equals(string))done = true;
}
public staticsynchronized void main(String[] args) throws InterruptedException {run() {
int i = numberOfTimes;
ContainerRandom containernumber = new ContainerRandom(123L);
Thread
thread = new Thread(container);
thread.start();
while(!done && i > 0) {
Thread.sleep(5000vector.add(number.nextInt(100));
container.shutdown() i--;
}
}
|
Compliant Solution (Interruptible)
This compliant solution stops the thread by using the Thread.interrupted()
method.
Code Block |
---|
|
public class Container implements Runnable }
}
public static void main(String[] args) throws InterruptedException {
private final Vector<String>Container vectorcontainer = new Vector<String>Container();
private final BufferedReaderThread inthread = new BufferedReader(new InputStreamReader(System.in)Thread(container);
thread.start();
public Vector<String> getVectorThread.sleep(5000) {;
container.shutdown();
}
}
|
Compliant Solution (Interruptible)
This compliant solution stops the thread by using the Thread.interrupted()
method.
Code Block |
---|
|
public class Container implements Runnablereturn vector;
}
public synchronized void run() {
private final StringVector<Integer> stringvector = nullnew Vector<Integer>();
private final doint {
numberOfTimes System.out.println("Enter another string");
try {
string = in.readLine();= 10;
public Vector<Integer> getVector() {
return vector;
}
public synchronized void run() {
int i }= catchnumberOfTimes;
(IOException e) {
Random number = new // Forward to handler
}Random(123L);
while(!Thread.interrupted() && i > 0) {
vector.add(stringnumber.nextInt(100));
} while (!Thread.interrupted() && !"END".equals(string)); 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();
}
}
|
...