A
Aziz
Hi,
The following code is an example from a book* where it shows some
errors in concurrent programming. I've actually typed and tried this
one, and it actually does what the author says but I do not understand
why. In my (obviously wrong) opinion the program should have run
without error.
It's a EvenGenerator which generates even integers in multiple
threads, and a EvenChecker, who checks if the number generated is
even?
*Bruce Eckel, Thinking in Java 4th ed, p.1150-1153
<code>
import java.util.concurrent.*;
abstract class IntGenerator {
private volatile boolean canceled = false;
public abstract int next();
public void cancel() {
canceled = true;
}
public boolean isCanceled() {
return canceled;
}
}
public class EvenGenerator extends IntGenerator {
private int currentEvenValue = 0;
public int next() {
++currentEvenValue; //danger point here
++currentEvenValue;
return currentEvenValue;
}
public static void main(String[] args) {
EvenChecker.test(new EvenGenerator());
}
}
class EvenChecker implements Runnable {
private IntGenerator generator;
private final int id;
public EvenChecker(IntGenerator g, int ident) {
generator = g;
id = ident;
}
public void run() {
while(!generator.isCanceled()) {
int val = generator.next();
if(val % 2 != 0) {
System.out.println(val + " not
even!");
generator.cancel();
}
}
}
public static void test(IntGenerator gp, int count) {
ExecutorService exec =
Executors.newCachedThreadPool();
for(int i = 0; i < count; i++)
exec.execute(new EvenChecker(gp, i));
exec.shutdown();
}
public static void test(IntGenerator gp) {
test(gp, 10);
}
}
</code>
Output: (an example)
89476993 not even!
89476993 not even!
My problem is, even the thread scheduler stops an EvenGenerator.next()
after the first ++currentEvenValue, next() doesn't return after the
second one, so I don't understand how the val variable (which is the
return value of next() ) in EvenChecker gets an odd number?
Thanks
The following code is an example from a book* where it shows some
errors in concurrent programming. I've actually typed and tried this
one, and it actually does what the author says but I do not understand
why. In my (obviously wrong) opinion the program should have run
without error.
It's a EvenGenerator which generates even integers in multiple
threads, and a EvenChecker, who checks if the number generated is
even?
*Bruce Eckel, Thinking in Java 4th ed, p.1150-1153
<code>
import java.util.concurrent.*;
abstract class IntGenerator {
private volatile boolean canceled = false;
public abstract int next();
public void cancel() {
canceled = true;
}
public boolean isCanceled() {
return canceled;
}
}
public class EvenGenerator extends IntGenerator {
private int currentEvenValue = 0;
public int next() {
++currentEvenValue; //danger point here
++currentEvenValue;
return currentEvenValue;
}
public static void main(String[] args) {
EvenChecker.test(new EvenGenerator());
}
}
class EvenChecker implements Runnable {
private IntGenerator generator;
private final int id;
public EvenChecker(IntGenerator g, int ident) {
generator = g;
id = ident;
}
public void run() {
while(!generator.isCanceled()) {
int val = generator.next();
if(val % 2 != 0) {
System.out.println(val + " not
even!");
generator.cancel();
}
}
}
public static void test(IntGenerator gp, int count) {
ExecutorService exec =
Executors.newCachedThreadPool();
for(int i = 0; i < count; i++)
exec.execute(new EvenChecker(gp, i));
exec.shutdown();
}
public static void test(IntGenerator gp) {
test(gp, 10);
}
}
</code>
Output: (an example)
89476993 not even!
89476993 not even!
My problem is, even the thread scheduler stops an EvenGenerator.next()
after the first ++currentEvenValue, next() doesn't return after the
second one, so I don't understand how the val variable (which is the
return value of next() ) in EvenChecker gets an odd number?
Thanks