[concurrency-interest] Concurrent sequential access to a mutable field without the volatile modifier
Sébastien Bocq
sebastien.bocq at gmail.com
Fri Jan 7 10:01:34 EST 2011
Hello,
I made a simple test (see below) to verify my assumption that a variable
mutated sequentially by multiple threads must be marked as volatile to have
mutations visible across these threads. How comes my test succeeds even
though I omitted the volatile keyword?
Thanks,
Sébastien
import java.util.concurrent.*;
public class VolatileTest {
static class CountTask implements Runnable {
public int count = 0; // volatile omitted
public void run() { count++; }
@Override
public String toString() {return String.valueOf(count);}
};
static class SimpleExecutor implements Runnable {
LinkedBlockingQueue<Runnable> queue = new
LinkedBlockingQueue<Runnable>();
public void submit(Runnable runnable) { queue.offer(runnable); }
volatile Thread thread = null;
public void run() {
thread = Thread.currentThread();
while (thread != null) {
try {
Runnable task = queue.take();
task.run();
} catch (InterruptedException e) {}
}
}
public void shutdown() {
Thread t = thread;
thread = null;
t.interrupt();
}
public SimpleExecutor() {
new Thread(this).start();
}
}
static class LoopTask implements Runnable {
CountDownLatch latch;
int count;
Runnable task;
SimpleExecutor[] executors;
/** Repeat a task sequentially using different executors
*
* @param executors the executors
* @param count the number of iterations
* @param latch latch decremented after the last iteration
* @param task the task invoked repeatedly
*/
public LoopTask(SimpleExecutor[] executors, int count,
CountDownLatch latch, Runnable task) {
this.executors = executors;
this.latch = latch;
this.count = count;
this.task = task;
}
public void run() {
if (count == 0)
latch.countDown();
else {
task.run();
executors[count % executors.length].submit(new
LoopTask(executors, count - 1, latch, task));
}
}
}
public static void main(String[] args) throws Exception {
int loops = 1000000;
int nbExecs = 10;
CountDownLatch latch = new CountDownLatch(1);
SimpleExecutor[] executors = new SimpleExecutor[nbExecs];
for (int i = 0; i < executors.length; i++)
executors[i] = new SimpleExecutor();
CountTask task = new CountTask();
try {
new LoopTask(executors, loops, latch, task).run();
latch.await();
System.out.println(task);
assert(task.count == loops);
} finally {
for (int i = 0; i < executors.length; i++)
executors[i].shutdown();
}
}
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20110107/d8b58217/attachment.html>
More information about the Concurrency-interest
mailing list