You are on page 1of 13

7/14/13

Producer Consumer Problem using Thread (Threads forum at JavaRanch)

A friendly place for programming greenhorns!

Big Moose Saloon


Search

Java FAQ

Recent Topics

Register / Login

JavaRanch Java Forums Java Threads and Synchronization

Author

Producer Consumer Problem using Thread


posted 6/28/2013 8:42:26 PM

V K Gupta Ranch Hand Joined: Aug 07, 2008 Posts: 55

Hi Friends, Please help me with the Producer Consumer Problem using Thread in Java. I have written the program for Producer Consumer Problem using Thread but my program is incomplete , so I want that somebody make the correction and addition in my program to make it complete so that i can understand Threads.

class A { int value; public void setA(int v) { value=v; } public int getA() { return value; } } class put implements Runnable { A obj; public void run() { for(int i=1;i<=10;i++) { System.out.println("putting in A value is " + i ); obj.setA(i); } } put(A ob) { obj=ob; } }

class get implements Runnable { A obj; get(A ob) { obj = ob; }

www.coderanch.com/t/614729/threads/java/Producer-Consumer-Thread

1/13

7/14/13

Producer Consumer Problem using Thread (Threads forum at JavaRanch)

public void run() { while(true) { System.out.println(obj.getA()); if(obj.getA() == 10) break; } } } public class X1 { public static void main(String arg[]) { A obj = new A(); put p = new put(obj); get g = new get(obj); Thread p1 = new Thread(p); Thread g2 = new Thread(g); p1.start(); g2.start(); } }

Chan Ag Ranch Hand Joined: Sep 06, 2012 Posts: 154

posted 6/30/2013 11:25:26 AM

You could tell us how you expect your program to behave. Do you mean your producer and consumer threads need to be synchronized? If yes, then what kind of synchronization are you looking for? Are you ok if the get thread misses a couple of values set by the other thread, i.e you just want that each of these threads taken separately behaves in a consistent way as regards the shared object-- this is relatively simple. Or do you also want that the updates to the state of the shared object are also not missed - in which case you might need to have some custom wait, notification logic build up. Also it seems, you aren't new to ranch. You might want to consider using the code tags to make your question readable. Also unless you don't have a strong reason to not follow Java naming conventions, I believe you might want to consider changing your class names and method names. Thanks, Chan.

V K Gupta Ranch Hand Joined: Aug 07, 2008 Posts: 55

posted 7/1/2013 1:23:17 PM

Thanks Chang Ag, I have re-written by program according to Java Conventions. Second Question ? I need producer and consumer thread to be synchronized . If producer produce one item then it should notify the consumer thread about it and after the consumer consume the item it should notify the producer to produce again and it should go on. consumer thread should not miss any produce item by the producer thread.

view plain

c opy to c lipboard

print

N ote: T ext c ontent in the c ode bloc ks is automatic ally word- wrapped

0 1 . 0 2 . 0 3 . 0 4 . 0 5 . 0 6 . 0 7 . 0 8 . 0 9 . 1 0 . 1 1 .

c l a s sI t e m{ i n tc o n t e n t ; p u b l i cv o i ds e t C o n t e n t ( i n tc o n t e n t ){ t h i s . c o n t e n t = c o n t e n t ; } p u b l i ci n tg e t C o n t e n t ( ){ r e t u r nc o n t e n t ; }

www.coderanch.com/t/614729/threads/java/Producer-Consumer-Thread

2/13

7/14/13
1 1 . 1 2 . 1 3 . 1 4 . 1 5 . 1 6 . 1 7 . 1 8 . 1 9 . 2 0 . 2 1 . 2 2 . 2 3 . 2 4 . 2 5 . 2 6 . 2 7 . 2 8 . 2 9 . 3 0 . 3 1 . 3 2 . 3 3 . 3 4 . 3 5 . 3 6 . 3 7 . 3 8 . 3 9 . 4 0 . 4 1 . 4 2 . 4 3 . 4 4 . 4 5 . 4 6 . 4 7 . 4 8 . 4 9 . 5 0 . 5 1 . 5 2 . 5 3 . 5 4 . 5 5 . 5 6 . 5 7 . 5 8 . 5 9 . 6 0 . 6 1 . 6 2 . 6 3 . 6 4 . } }

Producer Consumer Problem using Thread (Threads forum at JavaRanch)

c l a s sP r o d u c e ri m p l e m e n t sR u n n a b l e{ I t e mo b j I t e m ; P r o d u c e r ( I t e mo b j I t e m ){ t h i s . o b j I t e m = o b j I t e m ; } p u b l i cv o i dr u n ( ){ f o r ( i n ti = 1 ; i < = 1 0 ; i + + ){ S y s t e m . o u t . p r i n t l n ( " P u t t i n gt h ev a l u ei ni t e m"+i) ; o b j I t e m . s e t C o n t e n t ( i ) ; } } } c l a s sC o n s u m e ri m p l e m e n t sR u n n a b l e{ I t e mo b j I t e m ; C o n s u m e r ( I t e mo b j I t e m ){ t h i s . o b j I t e m=o b j I t e m ; } p u b l i cv o i dr u n ( ){ w h i l e ( t r u e ){ S y s t e m . o u t . p r i n t l n ( o b j I t e m . g e t C o n t e n t ( ) ) ; i f ( o b j I t e m . g e t C o n t e n t ( )= =1 0 ) b r e a k ; } } } p u b l i cc l a s s E x e c u t e { p u b l i cs t a t i cv o i dm a i n ( S t r i n ga r g [ ] ){ I t e mo b j I t e m=n e wI t e m ( ) ; P r o d u c e ro b j P r o d u c e r=n e wP r o d u c e r ( o b j I t e m ) ; C o n s u m e ro b j C o n s u m e r=n e wC o n s u m e r ( o b j I t e m ) ; T h r e a dp r o d u c e r T h r e a d=n e wT h r e a d ( o b j P r o d u c e r ) ; T h r e a dc o n s u m e r T h r e a d=n e wT h r e a d ( o b j C o n s u m e r ) ; p r o d u c e r T h r e a d . s t a r t ( ) ; c o n s u m e r T h r e a d . s t a r t ( ) ; } }

V K Gupta Ranch Hand Joined: Aug 07, 2008 Posts: 55

posted 7/1/2013 1:27:26 PM

please reply

Chan Ag Ranch Hand Joined: Sep 06, 2012 Posts: 154

posted 7/1/2013 3:15:53 PM

Ok, so this is sort of a rough draft of a response. Hence you should treat it as such. The point is I'm also studying Java Threads and I'm yet to start with wait() and notify() logic and their inherent intricacies. So while this solution works, it may break while you test it. Hence you might want to test it and make amends to it. I have a feeling that this ain't a good solution ( You see the redundancy, right? ). If you can wait, I may post a better solution later.

2
view plain c opy to c lipboard print ? N ote: T ext c ontent in the c ode bloc ks is automatic ally word- wrapped

www.coderanch.com/t/614729/threads/java/Producer-Consumer-Thread

0 1 . 0 2 . 0 3 . 0 4 . 0 5 . 0 6 . 0 7 . 0 8 . 0 9 . 1 0 . 1 1 . 1 2 .

p a c k a g eT h r e a d E x a m p l e s ; c l a s sI t e m{ v o l a t i l ei n tc o n t e n t ; p u b l i cs y n c h r o n i z e dv o i ds e t C o n t e n t ( i n tc o n t e n t ){ t h i s . c o n t e n t = c o n t e n t ; } p u b l i cs y n c h r o n i z e di n tg e t C o n t e n t ( ){ r e t u r nc o n t e n t ;

3/13

7/14/13
1 2 . 1 3 . 1 4 . 1 5 . 1 6 . 1 7 . 1 8 . 1 9 . 2 0 . 2 1 . 2 2 . 2 3 . 2 4 . 2 5 . 2 6 . 2 7 . 2 8 . 2 9 . 3 0 . 3 1 . 3 2 . 3 3 . 3 4 . 3 5 . 3 6 . 3 7 . 3 8 . 3 9 . 4 0 . 4 1 . 4 2 . 4 3 . 4 4 . 4 5 . 4 6 . 4 7 . 4 8 . 4 9 . 5 0 . 5 1 . 5 2 . 5 3 . 5 4 . 5 5 . 5 6 . 5 7 . 5 8 . 5 9 . 6 0 . 6 1 . 6 2 . 6 3 . 6 4 . 6 5 . 6 6 . 6 7 . 6 8 . 6 9 . 7 0 . 7 1 . 7 2 . 7 3 . 7 4 . 7 5 . 7 6 . 7 7 . 7 8 . 7 9 . 8 0 . 8 1 . 8 2 . 8 3 . 8 4 . 8 5 . 8 6 . 8 7 . 8 8 . 8 9 . 9 0 . 9 1 . 9 2 . 9 3 . 9 4 . 9 5 . 9 6 . 9 7 . 9 8 . 9 9 . 1 0 0 . 1 0 1 . 1 0 2 . 1 0 3 . } }

Producer Consumer Problem using Thread (Threads forum at JavaRanch)


r e t u r nc o n t e n t ;

c l a s sP r o d u c e ri m p l e m e n t sR u n n a b l e{ I t e mi t e m ; P r o d u c e r ( I t e mi t e m ){ t h i s . i t e m = i t e m ; } p u b l i cI t e mg e t I t e m ( ){ r e t u r ni t e m ; } p u b l i cv o i ds e t I t e m ( I t e mi t e m ){ t h i s . i t e m=i t e m ; } p u b l i cv o i dr u n ( ){ i n ti= 0 ; s y n c h r o n i z e d ( t h i s ) { w h i l e ( t r u e ) { + + i ; i f( i = = 1 0 )r e t u r n ; S y s t e m . o u t . p r i n t l n ( " P u t t i n gt h ev a l u ei ni t e m"+i ) ; i t e m . s e t C o n t e n t ( i ) ; n o t i f y ( ) ; t r y { w a i t ( ) ; } c a t c h ( I n t e r r u p t e d E x c e p t i o ne ) { e . p r i n t S t a c k T r a c e ( ) ; } } } } } c l a s sC o n s u m e ri m p l e m e n t sR u n n a b l e{ P r o d u c e rp r o d u c e r ; C o n s u m e r ( P r o d u c e rp r o d u c e r ){ t h i s . p r o d u c e r=p r o d u c e r ; }

p u b l i cv o i dr u n ( ) { s y n c h r o n i z e d ( p r o d u c e r ) { w h i l e ( t r u e ) { S y s t e m . o u t . p r i n t l n ( " C o n s u m i n g"+ p r o d u c e r . g e t I t e m ( ) . g e t C o n t e n t ( ) ) ; p r o d u c e r . n o t i f y ( ) ; t r y{ i f ( p r o d u c e r . g e t I t e m ( ) . g e t C o n t e n t ( )= =9 ) r e t u r n ; p r o d u c e r . w a i t ( ) ; }c a t c h( I n t e r r u p t e d E x c e p t i o ne ){ / /T O D OA u t o g e n e r a t e dc a t c hb l o c k e . p r i n t S t a c k T r a c e ( ) ; } } } } } p u b l i cc l a s s E x e c u t e { p u b l i cs t a t i cv o i dm a i n ( S t r i n ga r g [ ] ){ I t e mi t e m 1=n e wI t e m ( ) ; P r o d u c e rp r o d u c e r=n e wP r o d u c e r ( i t e m 1 ) ; C o n s u m e rc o n s u m e r=n e wC o n s u m e r ( p r o d u c e r ) ; T h r e a dp r o d u c e r T h r e a d=n e wT h r e a d ( p r o d u c e r ) ; T h r e a dc o n s u m e r T h r e a d=n e wT h r e a d ( c o n s u m e r ) ; p r o d u c e r T h r e a d . s t a r t ( ) ; c o n s u m e r T h r e a d . s t a r t ( ) ;

www.coderanch.com/t/614729/threads/java/Producer-Consumer-Thread

4/13

7/14/13
1 0 3 . 1 0 4 . 1 0 5 . } }

Producer Consumer Problem using Thread (Threads forum at JavaRanch)


c o n s u m e r T h r e a d . s t a r t ( ) ;

Request others to provide feedback, so we may all learn. Thanks, Chan.

Steve Luke Bartender Joined: Jan 28, 2003 Posts: 3159

posted 7/1/2013 7:08:36 PM

V K Gupta wrote:

please reply

6
I like...

Hi V K Gupta, You posted this all of four minutes after your previous post. The good folks on this forum are volunteers and have their own things to do: they aren't here to read and respond to your posts within seconds of your posting. Even if they were, allowing just four minutes between prods hardly gives time to understand the code you posted an provide a detailed response (after all if it were that easy you probably wouldn't have needed the help, you are clearly bright, so what is hard for you is not going to be easy for anyone else). So for next please EaseUp (<-- link). Chan, the response you gave is pretty good, but not perfect. You can get a situation where the output is not consistent. For example, if the producer gets the lock on itself first, then the output could be:
view plain c opy to c lipboard print ?

N ote: T ext c ontent in the c ode bloc ks is automatic ally word- wrapped

0 1 . 0 2 . 0 3 . 0 4 . 0 5 .

p r o d u c i n g1 c o n s u m i n g1 p r o d u c i n g2 c o n s u m i n g2 . . .

But if the consumer gets the lock on the producer first then the output could be:
view plain c opy to c lipboard print ?

N ote: T ext c ontent in the c ode bloc ks is automatic ally word- wrapped

0 1 . 0 2 . 0 3 . 0 4 . 0 5 .

c o n s u m i n g0 p r o d u c i n g1 c o n s u m i n g1 p r o d u c i n g2 . . .

A small difference, but that could mean an application 'sporadically' works or crashes if the consumer gets a value before the producer produces one. The second problem with it is that you have two synchronized locks in that code, and they are nested. One is the Item (the item's two methods are synchronized) and the second is the Producer. Worse yet is that the two locks are nested. In the code you have this isn't a problem, you use the locks correctly and always generate the locks in a consistent order (Producer then Item). But having nested locks like this can be dangerous and lead to deadlocks (much easier to happen if the code gets more complicated). My preference is to run on a single lock whenever possible. In your producer/consumer you could easily replace the lock on the Producer with the Item lock. You would pass the Item to the Consumer instead of the Producer. One final suggestion. Whenever possible I would suggest using the classes in the java.util.concurrent package. For example, in this scenario where you want the Producer to run once, then the consumer to run once, then repeat, using a SynchronousQueue is the ideal solution. You do not have to code your own Item class, and you do not have to code your own signaling. The SynchronousQueue does it for you. And if you reference the SynchronousQueue as a BlockingQueue, you make it easier to modify the Queue's behavior later on (for example, if you wanted to allow the Producer to run faster, you might substitute in an ArrayBlockingQueue to allow multiple items to be stored in order for the Consumer, and you wouldn't have to change any of the working code.)

Steve

Chan Ag Ranch Hand Joined: Sep 06,

posted 7/1/2013 9:29:34 PM

Greetings, Steve.

www.coderanch.com/t/614729/threads/java/Producer-Consumer-Thread

5/13

7/14/13

Joined: Sep 06, 2012 Posts: 154

Greetings, Steve.

Producer Consumer Problem using Thread (Threads forum at JavaRanch)

Thanks so much for such an informative and constructive feedback. I greatly appreciate it. 2 Based on your suggestions, I have reworked on my code to take care of point 1 ( what if consumer gets the lock first ) by having an extra condition in the run method of the Consumer that can issue an extra notify() if that condition is met. I'm not sure if this is a graceful solution to handle the issue-- it's like too many conditions based on hard coded data values which makes your system difficult to be reused ( Just a guess). I'd like to post my solution here so I could (hope to) get a feedback again but I can't steal this post from the OP who reserves the first right to work on it and may have a better solution than mine. So I'll wait for a while. :-) You almost provided us with the solution for point 2 ( nested locks ). So this part was easy. Thanks. BlockingQueue description provided by you seems like a very pretty solution. It seems like a nice advanced construct in Java that I'd like to cover as soon as I can. Once I've studied about it, I will come back to this post to implement this requirement ( point 1 might become very easy then ) using a BlockingQueue. Thanks, Chan.

Chan Ag Ranch Hand Joined: Sep 06, 2012 Posts: 154

posted 7/2/2013 11:12:34 AM

Greetings, It seems I didn't do it right the second time too. :-) The extra notify() and extra wait() was redundant and not 'properly planned' code. Skipping past how I didn't do it right the second time, here is my new solution.

2
view plain c opy to c lipboard print ? N ote: T ext c ontent in the c ode bloc ks is automatic ally word- wrapped

0 1 . 0 2 . 0 3 . 0 4 . 0 5 . 0 6 . 0 7 . 0 8 . 0 9 . 1 0 . 1 1 . 1 2 . 1 3 . 1 4 . 1 5 . 1 6 . 1 7 . 1 8 . 1 9 . 2 0 . 2 1 . 2 2 . 2 3 . 2 4 . 2 5 . 2 6 . 2 7 . 2 8 . 2 9 . 3 0 . 3 1 . 3 2 . 3 3 . 3 4 . 3 5 . 3 6 . 3 7 . 3 8 . 3 9 . 4 0 . 4 1 . 4 2 . 4 3 . 4 4 . 4 5 . 4 6 . 4 7 . 4 8 . 4 9 . 5 0 .

p a c k a g eT h r e a d E x a m p l e s ; c l a s sI t e m{ p r i v a t ev o l a t i l ei n tc o n t e n t ; p u b l i cv o i ds e t C o n t e n t ( i n tc o n t e n t ){ t h i s . c o n t e n t = c o n t e n t ; } p u b l i ci n tg e t C o n t e n t ( ){ r e t u r nc o n t e n t ; } } c l a s sP r o d u c e ri m p l e m e n t sR u n n a b l e{ p r i v a t eI t e mi t e m ; P r o d u c e r ( I t e mi t e m ){ t h i s . i t e m = i t e m ; }

p u b l i cv o i dr u n ( ){ i n ti= 0 ; s y n c h r o n i z e d ( i t e m ) { w h i l e ( t r u e ) { + + i ; i f( i = = 1 0 )r e t u r n ; S y s t e m . o u t . p r i n t l n ( " P r o d u c i n g"+i ) ; i t e m . s e t C o n t e n t ( i ) ; i t e m . n o t i f y ( ) ; t r y { i t e m . w a i t ( ) ; } c a t c h ( I n t e r r u p t e d E x c e p t i o ne ) { e . p r i n t S t a c k T r a c e ( ) ; } } } } }

www.coderanch.com/t/614729/threads/java/Producer-Consumer-Thread

6/13

7/14/13

5 0 . 5 1 . 5 2 . 5 3 . 5 4 . 5 5 . 5 6 . 5 7 . 5 8 . 5 9 . 6 0 . 6 1 . 6 2 . 6 3 . 6 4 . 6 5 . 6 6 . 6 7 . 6 8 . 6 9 . 7 0 . 7 1 . 7 2 . 7 3 . 7 4 . 7 5 . 7 6 . 7 7 . 7 8 . 7 9 . 8 0 . 8 1 . 8 2 . 8 3 . 8 4 . 8 5 . 8 6 . 8 7 . 8 8 . 8 9 . 9 0 . 9 1 . 9 2 . 9 3 . 9 4 . 9 5 . 9 6 .

Producer Consumer Problem using Thread (Threads forum at JavaRanch)


c l a s sC o n s u m e ri m p l e m e n t sR u n n a b l e{ p r i v a t eI t e mi t e m ; C o n s u m e r ( I t e mi t e m ){ t h i s . i t e m=i t e m ; } p u b l i cv o i dr u n ( ) { s y n c h r o n i z e d ( i t e m ) { w h i l e ( t r u e ) { i f( i t e m . g e t C o n t e n t ( ) ! = 0 ) S y s t e m . o u t . p r i n t l n ( " C o n s u m i n g"+ i t e m . g e t C o n t e n t ( ) ) ; i t e m . n o t i f y ( ) ; t r y { i f ( i t e m . g e t C o n t e n t ( )= =9 ) r e t u r n ; i t e m . w a i t ( ) ; } c a t c h( I n t e r r u p t e d E x c e p t i o ne ) { e . p r i n t S t a c k T r a c e ( ) ; } } } } } p u b l i cc l a s s E x e c u t e { p u b l i cs t a t i cv o i dm a i n ( S t r i n ga r g [ ] ){ I t e mi t e m 1=n e wI t e m ( ) ; / / n e wT h r e a d (n e wP r o d u c e r ( i t e m 1 ) ) . s t a r t ( ) ; n e wT h r e a d (n e wC o n s u m e r ( i t e m 1 ) ) . s t a r t ( ) ; n e wT h r e a d (n e wP r o d u c e r ( i t e m 1 ) ) . s t a r t ( ) ; } }

Am I doing it right this time ( let us put aside finer solutions involving BlockingQueue for now cause I will be able to get to those pretty things later I guess-- Much later)?

Thanks, Chan.

Steve Luke Bartender Joined: Jan 28, 2003 Posts: 3159

posted 7/2/2013 4:46:32 PM


Chan A g wrote:

Am I doing it right this time ( let us put aside finer solutions involving BlockingQueue for now cause I will be able to get to those pretty things later I guess-- Much later)?

6 You are, as long as...


I like...

view plain

c opy to c lipboard

print

N ote: T ext c ontent in the c ode bloc ks is automatic ally word- wrapped

www.coderanch.com/t/614729/threads/java/Producer-Consumer-Thread

0 1 . 0 2 . 0 3 . 0 4 . 0 5 . 0 6 . 0 7 .

c l a s sC o n s u m e ri m p l e m e n t sR u n n a b l e{ . . . p u b l i cv o i dr u n ( ) { . . . i f( i t e m . g e t C o n t e n t ( ) ! = 0 )

7/13

7/14/13
0 7 . 0 8 . 0 9 . 1 0 . } }

Producer Consumer Problem using Thread (Threads forum at JavaRanch)


i f( i t e m . g e t C o n t e n t ( ) ! = 0 ) S y s t e m . o u t . p r i n t l n ( " C o n s u m i n g"+ i t e m . g e t C o n t e n t ( ) ) ;

you know that zero is not a valid value. You make two such assumptions in your code: 1) that 0 means producing has not started, and 2) 9 is the last value. Again, in your specific case, that works. Do you think you could make the system work with any value?

Chan Ag Ranch Hand Joined: Sep 06, 2012 Posts: 154

posted 7/3/2013 1:26:44 AM

Thanks Steve for the feedback. I've been working on your suggestions. Yeah, even I don't like the assumptions ( the hard coded values) in the code. I've been trying to remove the dependency on hard coded values to start/stop/manage the producer and consumer logic. Didn't realize it would be so difficult but it turns out that it is/was ( depending on whether it is still close to at least a decent solution ). It has taken me a good amount of time to come up with even the current solution. I have used a helper class, SharedResource, that encapsulates the shared resource ( i.e Item object ) and a boolean contentChanged. Every time producer changes the value of the item object, it also sets this flag and consumer clears this flag after consuming the value. This change could take care of ensuring that the consumer consumed a value only after producer had produced one regardless of which thread started first. But once producer thread was dead, I could not find a nice logic to stop the consumer loop from waiting. All I could think of was making the consumer wait for a few seconds and if it does not receive a notification in that period and the content hasn't changed in this period, producer is likely dead. Not sure how else I can make consumer thread more intelligent. I also considered adding another flag in the SharedResource class called doneProducing or something that the producer could set and consumer could poll. But that idea didn't appeal to me much. But still, is that what good programmers should do? Here is what I have.

view plain

c opy to c lipboard

print

N ote: T ext c ontent in the c ode bloc ks is automatic ally word- wrapped

0 1 . 0 2 . 0 3 . 0 4 . 0 5 . 0 6 . 0 7 . 0 8 . 0 9 . 1 0 . 1 1 . 1 2 . 1 3 . 1 4 . 1 5 . 1 6 . 1 7 . 1 8 . 1 9 . 2 0 . 2 1 . 2 2 . 2 3 . 2 4 . 2 5 . 2 6 . 2 7 . 2 8 . 2 9 . 3 0 . 3 1 . 3 2 . 3 3 . 3 4 . 3 5 . 3 6 . 3 7 . 3 8 . 3 9 . 4 0 . 4 1 . 4 2 . 4 3 . 4 4 . 4 5 .

p a c k a g eT h r e a d E x a m p l e s ; c l a s sI t e m { p r i v a t ev o l a t i l ei n tc o n t e n t ; p u b l i cv o i ds e t C o n t e n t ( i n tc o n t e n t ) { t h i s . c o n t e n t=c o n t e n t ; } p u b l i ci n tg e t C o n t e n t ( ) { r e t u r nc o n t e n t ; } } c l a s sS h a r e d R e s o u r c e { p r i v a t eI t e mi t e m ; p r i v a t eb o o l e a nc o n t e n t C h a n g e d ; p u b l i cI t e mg e t I t e m ( ) { r e t u r ni t e m ; } p u b l i cb o o l e a ni s C o n t e n t C h a n g e d ( ) { r e t u r nc o n t e n t C h a n g e d ; } p u b l i cv o i ds e t C o n t e n t C h a n g e d ( b o o l e a nc o n t e n t C h a n g e d ) { t h i s . c o n t e n t C h a n g e d=c o n t e n t C h a n g e d ; } p u b l i cS h a r e d R e s o u r c e ( I t e mi t e m ) { s u p e r ( ) ; t h i s . i t e m=i t e m ; t h i s . c o n t e n t C h a n g e d=f a l s e ; }

www.coderanch.com/t/614729/threads/java/Producer-Consumer-Thread

8/13

7/14/13
4 5 . 4 6 . 4 7 . 4 8 . 4 9 . 5 0 . 5 1 . 5 2 . 5 3 . 5 4 . 5 5 . 5 6 . 5 7 . 5 8 . 5 9 . 6 0 . 6 1 . 6 2 . 6 3 . 6 4 . 6 5 . 6 6 . 6 7 . 6 8 . 6 9 . 7 0 . 7 1 . 7 2 . 7 3 . 7 4 . 7 5 . 7 6 . 7 7 . 7 8 . 7 9 . 8 0 . 8 1 . 8 2 . 8 3 . 8 4 . 8 5 . 8 6 . 8 7 . 8 8 . 8 9 . 9 0 . 9 1 . 9 2 . 9 3 . 9 4 . 9 5 . 9 6 . 9 7 . 9 8 . 9 9 . 1 0 0 . 1 0 1 . 1 0 2 . 1 0 3 . 1 0 4 . 1 0 5 . 1 0 6 . 1 0 7 . 1 0 8 . 1 0 9 . 1 1 0 . 1 1 1 . 1 1 2 . 1 1 3 . 1 1 4 . 1 1 5 . 1 1 6 . 1 1 7 . 1 1 8 . 1 1 9 . 1 2 0 . 1 2 1 . 1 2 2 . 1 2 3 . 1 2 4 . 1 2 5 . 1 2 6 . 1 2 7 . 1 2 8 . 1 2 9 . 1 3 0 . 1 3 1 . 1 3 2 . 1 3 3 . 1 3 4 . 1 3 5 . 1 3 6 . } }

Producer Consumer Problem using Thread (Threads forum at JavaRanch)

c l a s sP r o d u c e ri m p l e m e n t sR u n n a b l e { p r i v a t eS h a r e d R e s o u r c er e s o u r c e ; p r i v a t es t a t i cf i n a li n tp r o d u c i n g L i m i t=1 0 ; P r o d u c e r ( S h a r e d R e s o u r c er e s o u r c e ) { t h i s . r e s o u r c e=r e s o u r c e ; } p u b l i cv o i dr u n ( ) { S y s t e m . o u t . p r i n t l n ( " P r o d u c e rs t a r t e d " ) ; i n tc o u n t e r= 0 ; s y n c h r o n i z e d( r e s o u r c e ) { w h i l e( c o u n t e r<p r o d u c i n g L i m i t ) { w h i l e( r e s o u r c e . i s C o n t e n t C h a n g e d ( ) ) { t r y { S y s t e m . o u t . p r i n t l n ( " P r o d u c e rw a i t i n gf o rc o n s u m e r " ) ; r e s o u r c e . w a i t ( 2 0 0 0 ) ; i f( r e s o u r c e . i s C o n t e n t C h a n g e d ( ) ) { S y s t e m . o u t . p r i n t l n ( " C o n s u m e rl i k e l yd e a d .Im u s td i et o o . " ) ; r e t u r n ; } } c a t c h( I n t e r r u p t e d E x c e p t i o ne ){ e . p r i n t S t a c k T r a c e ( ) ; } } c o u n t e r + + ; S y s t e m . o u t . p r i n t l n ( " P r o d u c i n g"+c o u n t e r ) ; r e s o u r c e . g e t I t e m ( ) . s e t C o n t e n t ( c o u n t e r ) ; r e s o u r c e . s e t C o n t e n t C h a n g e d ( t r u e ) ; r e s o u r c e . n o t i f y ( ) ; } } } } c l a s sC o n s u m e ri m p l e m e n t sR u n n a b l e { p r i v a t eS h a r e d R e s o u r c er e s o u r c e ; C o n s u m e r ( S h a r e d R e s o u r c er e s o u r c e ) { t h i s . r e s o u r c e=r e s o u r c e ; } p u b l i cv o i dr u n ( ) { S y s t e m . o u t . p r i n t l n ( " C o n s u m e rs t a r t e d " ) ; s y n c h r o n i z e d( r e s o u r c e ) { w h i l e( t r u e ) { w h i l e( ! r e s o u r c e . i s C o n t e n t C h a n g e d ( ) ) { t r y { S y s t e m . o u t . p r i n t l n ( " C o n s u m e rw a i t i n gf o rp r o d u c e r " ) ; r e s o u r c e . w a i t ( 3 0 0 0 ) ; i f( ! r e s o u r c e . i s C o n t e n t C h a n g e d ( ) ) { S y s t e m . o u t . p r i n t l n ( " P r o d u c e rl i k e l yd e a d .Im u s td i et o o . " ) ; r e t u r n ; } } c a t c h( I n t e r r u p t e d E x c e p t i o ne ) { e . p r i n t S t a c k T r a c e ( ) ; } } S y s t e m . o u t . p r i n t l n ( " C o n s u m i n g"+r e s o u r c e . g e t I t e m ( ) . g e t C o n t e n t ( ) ) ; r e s o u r c e . s e t C o n t e n t C h a n g e d ( f a l s e ) ; r e s o u r c e . n o t i f y ( ) ; } } } } p u b l i cc l a s sE x e c u t e{

www.coderanch.com/t/614729/threads/java/Producer-Consumer-Thread

9/13

7/14/13
1 3 6 . 1 3 7 . 1 3 8 . 1 3 9 . 1 4 0 . 1 4 1 . 1 4 2 . 1 4 3 . 1 4 4 . 1 4 5 . 1 4 6 . 1 4 7 . 1 4 8 .

Producer Consumer Problem using Thread (Threads forum at JavaRanch)


p u b l i cc l a s sE x e c u t e{ p u b l i cs t a t i cv o i dm a i n ( S t r i n ga r g [ ] ){ S h a r e d R e s o u r c er e s o u r c e=n e wS h a r e d R e s o u r c e ( n e wI t e m ( ) ) ; / / n e wT h r e a d ( n e wP r o d u c e r ( r e s o u r c e ) ) . s t a r t ( ) ; / / f o r( i n ti=0 ;i<1 0 0 0 0 0 ;i + + ) ; n e wT h r e a d ( n e wC o n s u m e r ( r e s o u r c e ) ) . s t a r t ( ) ; f o r( i n ti=0 ;i<1 0 0 0 0 0 ;i + + ) ; n e wT h r e a d (n e wP r o d u c e r ( r e s o u r c e ) ) . s t a r t ( ) ; } }

Here are the two sets of outputs. Producer started Producing 1 Producer waiting for consumer Consumer started Consuming 1 Consumer waiting for producer Producing 2 Producer waiting for consumer Consuming 2 Consumer waiting for producer Producing 3 Producer waiting for consumer Consuming 3 Consumer waiting for producer Producing 4 Producer waiting for consumer Consuming 4 Consumer waiting for producer Producing 5 Producer waiting for consumer Consuming 5 Consumer waiting for producer Producing 6 Producer waiting for consumer Consuming 6 Consumer waiting for producer Producing 7 Producer waiting for consumer Consuming 7 Consumer waiting for producer Producing 8 Producer waiting for consumer Consuming 8 Consumer waiting for producer Producing 9 Producer waiting for consumer Consuming 9 Consumer waiting for producer Producing 10 Consuming 10 Consumer waiting for producer Producer likely dead. I must die too.

Consumer started Consumer waiting for producer Producer started Producing 1 Producer waiting for consumer Consuming 1 Consumer waiting for producer Producing 2 Producer waiting for consumer Consuming 2 Consumer waiting for producer Producing 3

www.coderanch.com/t/614729/threads/java/Producer-Consumer-Thread

10/13

7/14/13

Producing 3 Producer waiting for consumer

Producer Consumer Problem using Thread (Threads forum at JavaRanch)

Consuming 3 Consumer waiting for producer Producing 4 Producer waiting for consumer Consuming 4 Consumer waiting for producer Producing 5 Producer waiting for consumer Consuming 5 Consumer waiting for producer Producing 6 Producer waiting for consumer Consuming 6 Consumer waiting for producer Producing 7 Producer waiting for consumer Consuming 7 Consumer waiting for producer Producing 8 Producer waiting for consumer Consuming 8 Consumer waiting for producer Producing 9 Producer waiting for consumer Consuming 9 Consumer waiting for producer Producing 10 Consuming 10 Consumer waiting for producer Producer likely dead. I must die too. Is it better now? Is< stop after value hasn't changed even though the wait time is elapsed> a decent approach to stop the threads in this scenario? What would you say? Thanks and Greetings, Chan.

Steve Luke Bartender Joined: Jan 28, 2003 Posts: 3159

posted 7/3/2013 3:55:51 AM


Chan A g wrote:

But once producer thread was dead, I could not find a nice logic to stop the consumer loop from waiting. All I could think of was making the consumer wait for a few seconds and if it does not receive a notification in that period and the content hasn't changed in this period, producer is likely dead. Not sure how else I can make consumer thread more intelligent. I also considered adding another flag in the

6
I like...

SharedResource class called doneProducing or something that the producer could set and consumer could poll. But that idea didn't appeal to me much.

I am not a particular fan of the timeout approach, because it is rather delicate if the amount of time to do the production varies or there can be hickups (if it was always fast there would be little reason to use separate threads...) There are two normal approaches: 1) Set a flag. You already thought of this one, and I think the problem you seem to have with it is it is 'yet another flag' to set. To get around that (sort of) you could use a state instead of flags. For example:
view plain c opy to c lipboard print ?

N ote: T ext c ontent in the c ode bloc ks is automatic ally word- wrapped

0 1 .

p u b l i ce n u mD a t a S t a t e{I N I T ,P R O D U C E D ,C O N S U M E D ,D O N E}

Some state variable in SharedResources starts out as INIT. When the Producer first sets a value it sets the state to PRODUCED as it sets the new value, then waits for the CONSUMED state. When it has produced the last result, instead of setting the PRODUCED state it sets the DONE state. Meanwhile the Consume waits for the PRODUCED state, and gets the value. As it gets the value it sets the state to CONSUMED, then before waiting again it checks for the DONE state, and when it gets it, it stops. This way you get one variable which descriptively replaces both the contentChanged flag you already have and the productionComplete flag. 2) Use a PoisonPill. A PoisonPill is a specific object that the Producer sets that (a) never should come up as a natural value of

www.coderanch.com/t/614729/threads/java/Producer-Consumer-Thread

11/13

7/14/13

Producer Consumer Problem using Thread (Threads forum at JavaRanch)


2) Use a PoisonPill. A PoisonPill is a specific object that the Producer sets that (a) never should come up as a natural value of production and (b) when encountered causes the consumer to die. This is much easier to do using Object references than primitive data. An example:
view plain c opy to c lipboard print ?

N ote: T ext c ontent in the c ode bloc ks is automatic ally word- wrapped

0 1 . 0 2 . 0 3 . 0 4 . 0 5 . 0 6 . 0 7 . 0 8 . 0 9 . 1 0 . 1 1 . 1 2 . 1 3 . 1 4 . 1 5 . 1 6 . 1 7 . 1 8 . 1 9 . 2 0 . 2 1 . 2 2 . 2 3 . 2 4 . 2 5 . 2 6 . 2 7 . 2 8 . 2 9 . 3 0 . 3 1 . 3 2 . 3 3 . 3 4 . 3 5 . 3 6 . 3 7 . 3 8 . 3 9 . 4 0 . 4 1 . 4 2 .

c l a s sI t e m { p u b l i cs t a t i cf i n a lI n t e g e rP O I S O N _ P I L L=n e wI n t e g e r ( 1 ) ; p r i v a t ev o l a t i l eI n t e g e rc o n t e n t ; p u b l i cv o i ds e t C o n t e n t ( I n t e g e rc o n t e n t ) { t h i s . c o n t e n t=c o n t e n t ; } p u b l i cv o i dg e t C o n t e n t ( ) { r e t u r nt h i s . c o n t e n t ; } } c l a s sP r o d u c e r { / / . . . w h i l e( c o u n t e r<p r o d u c i n g L i m i t ) { / / . . . c o u n t e r + + ; S y s t e m . o u t . p r i n t l n ( " P r o d u c i n g"+c o u n t e r ) ; i t e m . s e t C o n t e n t ( c o u n t e r ) ; / / . . . } / / d o n ep r o d u c i n g ,k i l lt h ec o n s u m e r i t e m . s e t C o n t e n t ( I t e m . P O I S O N _ P I L L ) ; / / . . . } c l a s sC o n s u m e r { / / . . . w h i l e ( / *c o n d i t i o n . . . ?* /t r u e ) { / / . . . I n t e g e rv a l u e=i t e m . g e t C o n t e n t ( ) ; / /N o t e :U s et h e= =n o t. e q u a l s ( ) ,o n eo ft h o s ef e wi n s t a n c e sw h e r ew ec o m p a r e / /r e f e r e n c ee q u a l i t y :w ew a n tt od i eo nt h eP O I S O N _ P I L Lo n l y ,n o to na nI n t e g e rt h a th a p p e n s / /t oh a v et h es a m ev a l u ea si t . . . i f( v a l u e= =I t e m . P O I S O N _ P I L L ) { r e t u r n ;/ /c o n s u m e rd i e s } e l s e { / /. . .c o n s u m e rc o n t i n u e sw i t hv a l u e } } / / . . . }

4 3 . 4 4 . 4 5 . 4 6 . 4 7 . 4 8 . 4 9 . 5 0 . 5 1 . 5 2 . 5 3 . 5 4 .

Now, I haven't tested with Integers, I am not sure if there are gotchas in this particular code (but it would be easy to test, just cycle through -10 to 10 and make sure it doesn't kill the consumer). But this is the strategy I almost always implement my code (usually because I am not producing primitives, but more complex Data Access Objects). It also translates to using a Queue...

Chan Ag Ranch Hand Joined: Sep 06, 2012 Posts: 154

posted 7/3/2013 7:15:46 PM

public enum DataState { INIT, PRODUC ED, C ONSUMED, DONE }

Wow. This is brilliant. Four clean, neat enum objects. One reference. And it's sorted. Wow. Very creative. Wonder why I couldn't think of it. Thanks a lot, Steve.

I think the problem you seem to have with it is it is 'yet another flag' to set

www.coderanch.com/t/614729/threads/java/Producer-Consumer-Thread

12/13

7/14/13

Producer Consumer Problem using Thread (Threads forum at JavaRanch)


Yes, exactly. I felt all I was doing is - go create another flag. Every time. Come a new situation, all I could think of was have another flag. And the worst thing is this flag had to be a shared flag. I realize they use PoisonKill a lot many times in my current project and one of the default PoisonKill value they have here is the String "-999". But it's a different programming language ( a proprietary programming language). I didn't know there was a term for 'PoisonKill' values. I think it's a good idea depending on the implementation. For this case I think enum reference approach is better though. I say this because we are also setting Item content to the PoisonKill value and that is not where PoisonKill belongs. Also like you said, it's an int. I like your explanation of why if we'd ever use PoisonKill approach, we should always test using ==. Not sure if they've given due consideration to that in our project, but I'd check. Just a side note -Given that today I've started studying about volatile variables, I have also started re-evaluating my solution with respect to everything I'm studying. One of the things I kept on thinking about today was I have encapsulated item and the flag in an object and my run has a synchronized block on that object, not on item. So item can still be inconsistent. main() method still has item reference and hence I should have synchronized those blocks on item object. Also I was thinking content in Item is private and there are only getters and setters. Hence having content variable as a volatile variable was not a necessity. But again my synchronized blocks ( synchronized on another object) are accessing it - one is even doing a ++ operation on the content. So I should have it as volatile. And then I thought- should it be better to have synchronized blocks synchronize on resource.getItem(). Just explaining my state of mind. Not really seeking help with it currently cause I feel as I study further, my understanding will improve. Synchronized methods and blocks come next in the book I'm using as my reference. And if there are things I'd still need help with, I'm sure you guys will help me like you have so far. All this help means a lot to me. Thanks. Regards, Chan.

Chan Ag Ranch Hand Joined: Sep 06, 2012 Posts: 154

posted 7/5/2013 3:24:39 AM

I tried to find some of the answers myself, but it seems I still require guidance. I've posted my questions in a separate, new post. Here is the link, if you'd like to take a look. http://www.coderanch.com/t/615123/java/java/synchronized-blocks-methods I'd appreciate any help I can get on the subject. Thanks, Chan.

I agree. Here's the link: http://aspose.com/file-tools

subject: Producer Consumer Problem using Thread

Similar Threads Important, about threads static synchronized method Newbie Producer Consumer Problem Need help in code regarding join() Explain me this output (notify)
All times above are in your local time zone & format.T he current ranch time (not your local time) is Jul 14, 2013 08:24:49 .

Contact Us | Powered by JForum |

C opyright 1998-2013 Paul W he aton

www.coderanch.com/t/614729/threads/java/Producer-Consumer-Thread

13/13

You might also like