-
Bug
-
Resolution: Fixed
-
P3
-
6
-
b69
-
generic
-
generic
-
Verified
Doug Lea writes:
Tim Peierls wrote:
>>>>>> - The end result is a ClassCastException in
>>>>>> ScheduledFutureTask.compareTo() since schedule.. creates a private
>>>>>> ScheduledFutureTask that I can wrap, but passing my wrapper instance to
>>>>>> remove() (as in your example) is wrong since I don't inherit from the
>>>>>> private class (and obviously cannot). compareTo casts to the private
>>>>>> class.
>>
>>>>
>>>> Thanks for pointing this out! That seems like a bug in the
>>>> implementation of ScheduledFutureTask.compareTo. It's being held in a
>>>> DelayQueue<RunnableScheduleFuture> so it shouldn't assume that
>>>> everything is a ScheduledFutureTask.
>
>>
>> No one piped up about this, but it seems like a serious bug in
>> ScheduledFutureTask.compareTo. I'm not sure what the fix might be.
>>
Right. I've been sitting on the change below. At first, I
was unhappy that because it uses two uncoordinated calls
to get relative delay, so can possibly (rarely) misorder.
But since this risk exists with any comparable ordering of
relative delays, I think it is the best you can do without
requiring an absolute-time delay method on Delayed's, which,
even if we could add it, would lead to the usual problems
with absolute time (people changing clocks etc).
--- 148,168 ----
public int compareTo(Delayed other) {
if (other == this) // compare zero ONLY if same object
return 0;
! if (other instanceof ScheduledFutureTask) {
! ScheduledFutureTask<?> x = (ScheduledFutureTask<?>)other;
! long diff = time - x.time;
! if (diff < 0)
! return -1;
! else if (diff > 0)
! return 1;
! else if (sequenceNumber < x.sequenceNumber)
! return -1;
! else
! return 1;
! }
! long d = (getDelay(TimeUnit.NANOSECONDS) -
! other.getDelay(TimeUnit.NANOSECONDS));
! return (d == 0)? 0 : ((d < 0)? -1 : 1);
}
/**
Tim Peierls wrote:
>>>>>> - The end result is a ClassCastException in
>>>>>> ScheduledFutureTask.compareTo() since schedule.. creates a private
>>>>>> ScheduledFutureTask that I can wrap, but passing my wrapper instance to
>>>>>> remove() (as in your example) is wrong since I don't inherit from the
>>>>>> private class (and obviously cannot). compareTo casts to the private
>>>>>> class.
>>
>>>>
>>>> Thanks for pointing this out! That seems like a bug in the
>>>> implementation of ScheduledFutureTask.compareTo. It's being held in a
>>>> DelayQueue<RunnableScheduleFuture> so it shouldn't assume that
>>>> everything is a ScheduledFutureTask.
>
>>
>> No one piped up about this, but it seems like a serious bug in
>> ScheduledFutureTask.compareTo. I'm not sure what the fix might be.
>>
Right. I've been sitting on the change below. At first, I
was unhappy that because it uses two uncoordinated calls
to get relative delay, so can possibly (rarely) misorder.
But since this risk exists with any comparable ordering of
relative delays, I think it is the best you can do without
requiring an absolute-time delay method on Delayed's, which,
even if we could add it, would lead to the usual problems
with absolute time (people changing clocks etc).
--- 148,168 ----
public int compareTo(Delayed other) {
if (other == this) // compare zero ONLY if same object
return 0;
! if (other instanceof ScheduledFutureTask) {
! ScheduledFutureTask<?> x = (ScheduledFutureTask<?>)other;
! long diff = time - x.time;
! if (diff < 0)
! return -1;
! else if (diff > 0)
! return 1;
! else if (sequenceNumber < x.sequenceNumber)
! return -1;
! else
! return 1;
! }
! long d = (getDelay(TimeUnit.NANOSECONDS) -
! other.getDelay(TimeUnit.NANOSECONDS));
! return (d == 0)? 0 : ((d < 0)? -1 : 1);
}
/**