• Post Reply Bookmark Topic Watch Topic
  • New Topic

Queuing  RSS feed

 
Hunter Dash
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Consider the below program:

I need your help here.
Every second or so the threads wakes up and writes everything in Quelist vector to Test.log file. During this process my understanding is it is going to lock the Quelist vector not allowing addmessage method to write any messages to it. I would like to have an implementation where when committing the messages to file i would like the program continue to write to the vector. Sort of queuing...
One thing i thought about doing is cloning the vector in write messages method and clearing the quelist vector and unlock the vector... but I am not sure whether it is a good idea. Because cloning will probably take some time as well...
Any help is appreciated...
[This message has been edited by Jim Yingst (edited November 26, 2000).]
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ugh - I tried adding [ code ] tags to make the indentation more readable, but it doesn't seems to have helped much. Ah well...
I'm not sure just what you're trying to do hare, but the QueList Vector is not locked continuously for the entire writeMessages() method. Rather, it is locked at the beginning of each individual Vector method (isEmpty(), size(), and elementAt() in this case), and unlocked when that method ends. So there are many times within writeMessages() when the Vector is not locked, and can be written to. Although, since the size() method is only used once at the beginning of the writeMessages(), if the Vector grows during loop execution you don't have any way to detect it. The loop will never see the later elements until writeMessages() is restarted, since rowCount stores the original value only - it doesn't check to see if the value has increased. If you want it to check each time, then call size() for the loop end condition rather than outside the loop.
You say something about clearing the Vector, but in the code shown you just keep adding elements, never removing them. I'd suggest that the writeMessages() method could always look at the first message in the Vector, write it, and remove it:
<code><pre> while (QueList.size() > 0) {
out.write(QueList.elementAt(0).toString().getBytes());
QueList.remove(0);
}</pre></code>
As long as other threads never remove elements, and only add other elements at the other end of the Vector, this should work fine. Never use the index of a Vector element from another thread, as it may change from line to line due to elements being removed.
 
Hunter Dash
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the reply Jim. I am sorry i have pasted the wrong writemessges method in my original post. Please find the new writemessages method in this post. what i want accomplish is improve the performace of the program by reducing the IO contention. the writemessges basically commits everything in the quelist vector to a test.log file (during which i think quevecor is locked). I don't want any locks on the quelist vector beacuse it does not allow me to add any new elements during that time (I guess). I am basicaly looking for some sort of queing mechansim by which i would like to add elements to quelist vector with out any contention...
thanks.

([ code ] tags added again by Jim for readability)
[This message has been edited by Jim Yingst (edited November 27, 2000).]
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hmmm... you really need to pick some names for your variables, and stay with them. I assume that QueList and printQueList are supposed to be the same, as are Queclone and printQueueclone. (Your capitalization seems somewhat random as well.) Anyway...
Originally posted by Hunter Dash:
the writemessges basically commits everything in the quelist vector to a test.log file (during which i think quevecor is locked). I don't want any locks on the quelist vector beacuse it does not allow me to add any new elements during that time (I guess). I am basicaly looking for some sort of queing mechansim by which i would like to add elements to quelist vector with out any contention...

I think there's always going to be some contention if you want the method to be thread-safe - the goal is to minimize this effect then. Let me first reiterate - the Vector is not locked for the whole of the writeMessages() method. It's only locked for brief portions (the Vector method calls) and unlocked in between. In fact, consider these two (fixed) lines of your method:
<code><pre> Queclone = (Vector) QueList.clone();
QueList.clear();</pre></code>
QueList is locked during the clone() method, and also during the clear() method. However, in between these two methods the lock is released. Even though the two methods are on adjacent lines, it is possible (though unlikely) that another thread could add a message to the queue after the clone() and before the clear(). If this happens, the message will be lost in the clear(), never to be printed. To avoid this, you need locking between the method calls, which could only be achived with the synchronized keyword. We don't want to make the whole method synchronized, so use a block:
<code><pre> synchronized (QueClone) {
Queclone = (Vector) QueList.clone();
QueList.clear();
}</pre></code>
You only need to protect the Vector between those two methods, I think. The rest of the method can stay outside the sync block.
So, is this faster than the alternative I suggested in my first post? I don't know - is it quicker to clone a Vector and clear it, or remove its elements one by one? Try it each way and see, I suppose.
 
mohit joshi
Ranch Hand
Posts: 243
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As Jim said, to make your code thread safe you need to synchronize the block.
If you synchronize (on the Vector Object, which is the correct thing to do) the whole operation of getting the Object reference from vector, writing to file and removing it, and you also want to simultaneously write new Objects to the Vector(i.e. you dont consider it important to synchronize the write to Vector code), then instead of Cloning, consider ArrayList, whose methods are not inherently synchronized.
By all means look at the documentation for the implication of using the ArrayList.add(Object) in nonsynchronized code.
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think that you need the add() methods synchronized too. ArrayList is not designed to handle more than one thread accessing its methods at a time. The reason to sync the read & remove is to prevent an add from happening at the same time. If add is not synced, then the sync on read & remove has no effect - it can't prevent add from occurring unless add is also synced.
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!