Concurrency problem

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
 
H

hiwa

next() doesn't return after the
second one
The first one was even so the second one was odd.
This is a typical normal result of a multi-threaded concurrency
without proper synchronization.
 
P

Patricia Shanahan

Aziz wrote:
....
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());
}
} ....
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?

The problem is that a single EvenGenerator instance is shared by
multiple threads. Think about what happens if Thread A does one, but not
both, of its increments, and then Thread B gets control and is at the
start of a next() call.

Patricia
 
H

hiwa

hiwa ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸:
The first one was even so the second one was odd.
This is a typical normal result of a multi-threaded concurrency
without proper synchronization.
Oh, let me rectify my post.

Correct description would be:

The failing thread did begin the two increments after another thread
just had done the first increment. The initial valur of var was odd for
the failing thread. Thus, the result was odd.

Or, when the failing thread did the second increment, the value of
var was even as the result of another thread had just done its
next() method.

Anyway it is a normal typical result of non-synchronizatioin.
 
A

Aziz

The problem is that a single EvenGenerator instance is shared by
multiple threads. Think about what happens if Thread A does one, but not
both, of its increments, and then Thread B gets control and is at the
start of a next() call.

Patricia

Thank you Patricia, now it's clear...
 
A

Aziz

Or, when the failing thread did the second increment, the value of
var was even as the result of another thread had just done its
next() method.

Anyway it is a normal typical result of non-synchronizatioin.


Thanks...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,744
Latest member
CortneyMcK

Latest Threads

Top