aspose file tools*
The moose likes Threads and Synchronization and the fly likes Newbie Producer Consumer Problem Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of EJB 3 in Action this week in the EJB and other Java EE Technologies forum!
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "Newbie Producer Consumer Problem" Watch "Newbie Producer Consumer Problem" New topic
Author

Newbie Producer Consumer Problem

Tirthankar Mukherjee
Ranch Hand

Joined: Apr 08, 2006
Posts: 51


Expected output like :

Grain Produced is : 1
Grain Consumed is : 1
Grain Produced is : 2
Grain Consumed is : 2


but getting like this :

Grain Produced is : 1
Grain Produced is : 2
Grain Consumed is : 1
Grain Consumed is : 2

Even Worse :


Grain Produced is : 11
Grain Consumed is : 11
Grain Consumed is : 12 =====>>> ???
Grain Produced is : 12


Final Output received


First of all I cant understand why
Producer 1
Producer 2
Consumer 1
Consumer 2

can be a valid output as read in book.

Secondly where is the problem in my code that makes to consume earlier than producing ??

Please Help, thanks in Advance
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11277
    
  59

Very interesting problem. I suspect the problem is with your System.out.println() statements.

If we look at just the run method of the Producer, we see:

Now the ProduceGrain method is synchronized, so the ConsumeGrain cannot run within that method. But nothing else in the Producer class is synchronized, so the moment you exit the ProduceGrain method the JVM is free to swap to another thread - even before the System.out.println statement is executed.

You could move the System.out.println statement into the ProduceGrain method (and the same for the ConsumeGrain's output), or you could synchronize all the code within the respective run methods.


The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 3932
    
  17

The problem isn't that your consumer ever executes before the producer. The problem is that your reporting mechanism (the System.out.printlns) are outside your synchronized block. Which means that the production and reporting of the production is not a single atomic unit. It is two separate units. Similarly the consumption and reporting of the consumption is not a single execution unit. Because they are not in the same synchronized block, then the Thread context can switch between the Production statement and the Reporting statement, allowing the Consumer to execute between the two.

These are the four steps you need to happen:
1) Production (grain count is incremented and grain is made available)
2) Production is reported (grain count is printed to System.out)
3) Consumption (grain count consumed and grain is made unavailable)
4) Consumption is reported (grain count consumed is printed to System.out)


With your code this is possible:

1) Production (grain count is incremented and grain is made available)
2) Consumption (grain count consumed and grain is made unavailable)
3) Consumption is reported (grain count consumed is printed to System.out)
4) Production is reported (grain count is printed to System.out)

As is this:

1) Production (grain count is incremented (1) and grain is made available)
2) Production is reported (grain count is printed (1) to System.out)
3) Consumption (grain count consumed (1) and grain is made unavailable)
4) Production (grain count is incremented (2) and grain is made available)
5) Production is reported (grain count is printed (2) to System.out)
6) Consumption is reported (grain count consumed is printed (1) to System.out)
7) Consumption (grain count consumed (2) and grain is made unavailable)
8) Consumption is reported (grain count consumed is printed (2) to System.out)


So how would you fix it?

edit == Dern, too slow.


Steve
Tirthankar Mukherjee
Ranch Hand

Joined: Apr 08, 2006
Posts: 51
Many many thanks to both of you Andrew Monkhouse and Steve Luke . I found my problem.

@Andrew

You could move the System.out.println statement into the ProduceGrain method (and the same for the ConsumeGrain's output), or you could synchronize all the code within the respective run methods.


I synchronized the run method but it did not work out ... but making the outputs atomic by putting them in their respective synchronized code worked really well.


@Steve

I fixed it by putting the output statements to the respective synchronized block. You really explained my problem very clearly, I got some better idea now.

Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11277
    
  59

Tirthankar Mukherjee wrote:Many many thanks to both of you Andrew Monkhouse and Steve Luke . I found my problem.

@Andrew

You could move the System.out.println statement into the ProduceGrain method (and the same for the ConsumeGrain's output), or you could synchronize all the code within the respective run methods.


I synchronized the run method but it did not work out ... but making the outputs atomic by putting them in their respective synchronized code worked really well.

True - synchronizing the run method will not work, however it would be possible to synchronize all the code within the run method. Consider:

Of course this would make the method synchronization on ProduceGrain redundant. This type of synchronization can be worth considering if you have other logic that should be synchronized but does not really belong within a particular method.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Newbie Producer Consumer Problem
 
Similar Threads
explain the output of this example that uses threads
Thread wait() and notify()
Not sure why this code is deadlocking (From my SCJP book)
Multithreaded Example... Where to put WAIT() , NOTIFY() advise please
Two questions uppon a deitel's project