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.