Testing Race Conditions in Java
October 12th, 2009 | Published in Google Open Source
Can you spot the bug in the following piece of Java code?
/** Maintains a list of names. */
public class NameManager {
private List names = new ArrayList();
/** Stores a new list of names. This method is threadsafe. */
public void setNames(List newNames) {
synchronized (names) {
names = new ArrayList();
for (String name : newNames) {
names.add(name);
}
}
}
(Hint: the method setNames() is synchronized on the names field, but that field is then modified to point to a new object.)
Thread Weaver is released as an open source project under the Apache license, and is available on Google Code. Many examples can be found in the initial documentation. If you have comments or questions, please see our discussion group. Happy testing!
Ed. Note: Post updated with corrected formatting.
/** Maintains a list of names. */
public class NameManager {
private List
/** Stores a new list of names. This method is threadsafe. */
public void setNames(List
synchronized (names) {
names = new ArrayList
for (String name : newNames) {
names.add(name);
}
}
}
(Hint: the method setNames() is synchronized on the names field, but that field is then modified to point to a new object.)
OK, so spotting the bug was easy. But how would you write a Unit Test to demonstrate the problem? You would need to have two or more threads calling setNames() simultaneously, but you still don't have any control over how the threads will be scheduled.
Enter Thread Weaver, a test framework that lets you control thread execution. By setting breakpoints in your code, you can stop one thread at exactly the point that you want, and then allow a second thread to run. This allows you to write repeatable multi-threaded unit tests, without relying on the thread scheduler.
Ed. Note: Post updated with corrected formatting.
By Alasdair Mackintosh, Software Engineering Team