*
The moose likes Threads and Synchronization and the fly likes Blocking queue Implementation Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of OCM Java EE 6 Enterprise Architect Exam Guide this week in the OCMJEA forum!
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "Blocking queue Implementation " Watch "Blocking queue Implementation " New topic
Author

Blocking queue Implementation

Atul Mishra
Ranch Hand

Joined: Jun 08, 2006
Posts: 140
Hi all,

I am implementing blocking queues like this

1. Class 1 which is a thread. Run method takes objects from the queue and performs db updates

2. Class 2 creates this queue. It reads results from the db and creates objects. These objects are put into the blocking queue by Class2. Class2 then initilizes 3 instances of Class 1 and operates on objects in parallel.

Is it a good implementation ?

Being more ellaborate,

Class 1 is just the thread implementation. Class1 extends Thread that is, where the run method takes the object from the queue and call the method to update values to the db.

Class2 is just a plain class.
The objects are like data objects created as a representation of each row in the DB. Class2 selects significant rows from the database and iterates through the resultset.
While iterating through the resultset the objects are being "put" into the queue.

So Class2 is not implemented as a thread.
For me the aim is Class1 - I need to do the db updates on a
more quicker format.

Please point out the problems in this implementation.

I always read about both producer and consumer being implemented as Runnable. but in my case Consumer like implementaion is a thread and producer is a normal class.

Thanks
Atul
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

1) You are better off making Class 1 implement Runnable, then generating a Thread to run it. From the perspective of 'OO philosophy' you should favor using the interface rather than extending the class since it gives you more flexibility. As a practical side, the Thread class itself can produce a lot of un-predicted and un-documented behavior for classes that extend it. You avoid those situations by implementing Runnable.

2) Otherwise your design is fine. Your producer, Class 2, is probably running in the 'main' Thread. The consumer is then running in its own Thread so the two run in parallel. Just make sure you don't execute the producer's code in a GUI environment from the event dispatch thread (ie directly from an action listener triggered from a button push).


Steve
Atul Mishra
Ranch Hand

Joined: Jun 08, 2006
Posts: 140
1) You are better off making Class 1 implement Runnable, then generating a Thread to run it. From the perspective of 'OO philosophy' you should favor using the interface rather than extending the class since it gives you more flexibility. As a practical side, the Thread class itself can produce a lot of un-predicted and un-documented behavior for classes that extend it. You avoid those situations by implementing Runnable.


Thank you Steve. I sure will give it a try.

2) Otherwise your design is fine. Your producer, Class 2, is probably running in the 'main' Thread. The consumer is then running in its own Thread so the two run in parallel. Just make sure you don't execute the producer's code in a GUI environment from the event dispatch thread (ie directly from an action listener triggered from a button push).


Yes Class 2 is running in the main thread. Consumer is in its own thread and its not running in a GUI environment.

In parallel, i was reading about the Producer/Consumer implementation as well and got into trying it as well.

The main question I get is how will I mark the thread to stop.
First I inserted an empty object at the end of the queue after the ResultSet iterations have been completed. Then when I take from the queue, I check
if queue == null and also I check whther the object I retrieved is an empty one.

Any better ways where I can mark when to stop running the thread ?

Thanks much
Atul
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

There are typically 2 ways to do it:

1) The Poison Pill, which is pretty much the situation you define - you place an Object in the Queue which the Consumer checks for and if it gets it the Consumer dies.
2) Make the Thread which runs the Consumer a daemon thread. If the application is shutting down and the only active threads are daemon threads then the application will continue to shut down - the Consumer will not keep running even when the Producing main thread is finished.

I like #1 because it ensures that the tasks in the Queue get completed before shutdown, but your situation may be different.
Atul Mishra
Ranch Hand

Joined: Jun 08, 2006
Posts: 140
Steve,

Regarding the implementation I had, when I moved to the server I am noticing that the thread is shutting down without working on some objects.

Looks like the producer produces the objects faster and the consumer becomes slower.
How can I make sure that the consumer is working on ALL objects in the queue before shutting down the thread

Thanks
Atul Mishra
Ranch Hand

Joined: Jun 08, 2006
Posts: 140
Steve,
could you please provide your thoughts ?

Thank you
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

You should be using the Poison Pill approach and NOT the daemon thread approach. If you use the Poison Pill, then the Pill becomes the last object in the queue and the thread won't shut down until it is reached. You should be careful if you actually use 'null' as the Poison Pill, because 'null' may be added into the queue intentionally. I would suggest actually using a fixed Object:


If that isn't working then chances are you are doing something more aggressive to shutdown your Consumer, like interrupting it. I would have to see a code example to see what is going on.
Atul Mishra
Ranch Hand

Joined: Jun 08, 2006
Posts: 140
Thanks Steve.

Please provide your suggestions.

I am thinking that since my consumer has some work to do, the poison is getting consumed before the work finishes.

and thats why the program terminates without working on all objects.

here is a code sample from my layout.

Producer: Class1 - which creates 2 threads.






But I am also suspecting my main class which calls Class1

here is how the mainprogram looks like



Since the consumer is bein invoked from Class1, I am not checking whether consumer has finished processing. So that
could be the problem right ?

So from the Class1 will I be able to return a variable after the thread finishes processing and then issue a main shutdown ?

Thanks, sorry for the too many questions. Learning by doing
Atul
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

Assuming that the call validateOb(objectFromQueue) doesn't itself start a new Thread, then the code you provide can not encounter the toTerminate object until the other objects, already retrieved from the queue, have already been processed. So, again assuming [tt]calidateOb/tt] doesn't start a new thread, the only ways the Workers can come to an end are if they are interrupted or if some other Test in the queue has a null name.

So, like I suggested last post, instead of checking if some value in Testis null, which may happen for some other reason, use a specific object to represent the Stop condition:



All based on my assumption that vaalidateOb does not start a new Thread. If it does, well then, don't do that run the validation code inside the Worker Thread.


So from the Class1 will I be able to return a variable after the thread finishes processing and then issue a main shutdown ?


You could provide a signal from the Worker to Class1 when the Thread completes, or you could cycle through the Threads you create for the Workers and join() them. But this won't solve the problem. The problem appears to be that the Workers are getting the signal to shutdown too early - which points to improper signal for the end of the Queue.
Atul Mishra
Ranch Hand

Joined: Jun 08, 2006
Posts: 140
Thank you Steve.
Yes the Poison approach did work. I tried out in so many different ways as well.

Thanks much
Atul
 
 
subject: Blocking queue Implementation