Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / June 2006

Tip: Looking for answers? Try searching our database.

Concurrency problem

Thread view: 
Aziz - 13 Jun 2006 00:39 GMT
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
hiwa - 13 Jun 2006 01:37 GMT
> 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 - 13 Jun 2006 02:01 GMT
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.
Aziz - 13 Jun 2006 10:02 GMT
>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...
Patricia Shanahan - 13 Jun 2006 01:45 GMT
...
> public class EvenGenerator extends IntGenerator {
>     private int currentEvenValue = 0;
[quoted text clipped - 8 lines]
>     }
> }
...
> 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
Aziz - 13 Jun 2006 10:02 GMT
>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...


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.