• Post Reply Bookmark Topic Watch Topic
  • New Topic

How DelayQueue work with Delayed interface

 
S Majumder
Ranch Hand
Posts: 349
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi All,
I have a question on DelayQueue . I have written one code and tested how it works internally .I am sharing the code here .


As you have seen here I am doing sorting by descending order on deleyTime .But the result is showing different .
The output is :

51
15
25
5
-15
10
5

Can anybody please explain why the order is not descending .

Thanks in advance .

Sb
 
Maxim Karvonen
Ranch Hand
Posts: 121
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi

Look at the line 48 in your code. Your Delayed instances are already expired because System.currentTimeMillis() returns quite large values. So all your items could be immediately taken out of the queue. Probably this is the reason why you see that output matches initial order.

Anyway, DelayQueue does not offer "iterate in sort order" guarantee. It only guarantees that items could not be taken before they expire. And do not expect to see sorted output even after providing positive delays. I think that DelayQueue uses heap data structure internally. It does not keeps items sorted. The only guarantee is that "you can extract items in order", but not "you can iterate items in order". PriorityQueue exhibits similar behaviour. Proper way to test the queue would be to provide positive delays and then extract items one by one.

P.S. Did you notice that in lines 48-49 you are dealing with milliseconds (currentTimeMillis) but pretend they are nanoseconds?
 
S Majumder
Ranch Hand
Posts: 349
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Maxim ,
You have nicely put on the explanation .
Can you please explain this ...

The only guarantee is that "you can extract items in order", but not "you can iterate items in order"


When I tried to debug the class , I found the order is not DESC in the Dqueue .

Here is the screen shot .

Thanks ,
Sb
Untitled.png
[Thumbnail for Untitled.png]
 
S Majumder
Ranch Hand
Posts: 349
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Maxim,
the


function is being called when we use the take() of the Dqueue . Correct me if I wrong .

I have modified the getDelay(TimeUnit unit) function to like this :



But I got the same output that I mentioned on my first post .

Sb
 
Maxim Karvonen
Ranch Hand
Posts: 121
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi

I meant that you have to use take method to get items in order. Iterating through the queue using iterator would not give you a sorted sequence. Your screenshot shows that is is definitely not a desc order in the array. But this is a queue, it is not an array. Queue order is descending here. In other words, items would be taken out correctly. If you use take method instead iterator, you would see a sorted sequence.

I looked into your code once again. Check compareTo method in your first post. It is not consistent with the delay order (and actually it is an opposite order). It says that item with deleyTime=10 is before item with deleyTime=5. It should be opposite. Items with lesser delay should be less than items with greater delay. This would not give you a sorted sequence by itself. But fixing this along with using take method would give you items with the increasing deleyTime.

According getDelay function. It is not guaranteed when this function would be called. Current implementation calls this method inside take and poll methods. But this can be changed in future version. For example, this method could be called once when item is put into the queue and delay value would be stored.
 
S Majumder
Ranch Hand
Posts: 349
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Maxim Karvonen wrote:
I looked into your code once again. Check compareTo method in your first post. It is not consistent with the delay order (and actually it is an opposite order). It says that item with deleyTime=10 is before item with deleyTime=5. It should be opposite. Items with lesser delay should be less than items with greater delay. This would not give you a sorted sequence by itself. But fixing this along with using take method would give you items with the increasing deleyTime.



Hi Maxim ,
Thanks again for the explanation.....
Could you give a short example how to implement comapreTo method properly.


Satya
 
S Majumder
Ranch Hand
Posts: 349
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Maxim,
You are correct , when I call the take() the application pop data desc / asc , according to the compareTo()'s implementation.

Satya
 
Maxim Karvonen
Ranch Hand
Posts: 121
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi, Satya

S Majumder wrote:Could you give a short example how to implement comapreTo method properly. Satya

You already have correct code commented out inside your implementation of compareTo. It is "ASC" sorting. Just uncomment it and comment your DESC section. I see that you was able to get items in ascending order in your last post. It is exactly what I was talking about.

If you need just specific order but not delays, you could use PriorityQueue. And for DelayQueue you have to have compareTo consistent with getDelay implementation (it is ascending order in your example). Otherwise DelayQueue's behaviour would be counterintuitive (it would wait longest timeout instead of shortest and this may change in future versions) and hard to debug.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!