Concurrency problem

Discussion in 'Java' started by Aziz, Jun 13, 2006.

  1. Aziz

    Aziz Guest

    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
     
    Aziz, Jun 13, 2006
    #1
    1. Advertising

  2. Aziz

    hiwa Guest

    > 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.
     
    hiwa, Jun 13, 2006
    #2
    1. Advertising

  3. 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
     
    Patricia Shanahan, Jun 13, 2006
    #3
  4. Aziz

    hiwa Guest

    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.

    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.
     
    hiwa, Jun 13, 2006
    #4
  5. Aziz

    Aziz Guest

    On Tue, 13 Jun 2006 00:45:14 GMT, Patricia Shanahan <>
    wrote:


    >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...
     
    Aziz, Jun 13, 2006
    #5
  6. Aziz

    Aziz Guest

    On 12 Jun 2006 18:01:25 -0700, "hiwa" <> wrote:


    >
    >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...
     
    Aziz, Jun 13, 2006
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Artur Sorszegi
    Replies:
    1
    Views:
    468
    Scott Allen
    Jul 29, 2004
  2. =?Utf-8?B?SmFzb24gQ2h1?=

    Concurrency problem

    =?Utf-8?B?SmFzb24gQ2h1?=, Dec 6, 2005, in forum: ASP .Net
    Replies:
    4
    Views:
    1,363
    =?Utf-8?B?SmFzb24gQ2h1?=
    Dec 7, 2005
  3. Replies:
    0
    Views:
    538
  4. Hunk
    Replies:
    10
    Views:
    1,016
  5. Mr B

    Concurrency problem

    Mr B, Mar 12, 2007, in forum: Java
    Replies:
    6
    Views:
    328
    Daniel Pitts
    Mar 13, 2007
Loading...

Share This Page