river-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Peter Firmstone <j...@zeus.net.au>
Subject Re: TaskManager progress
Date Thu, 22 Jul 2010 10:39:25 GMT
Patricia Shanahan wrote:
> You make some interesting points in your e-mails. I'm just going to
> comment on a couple of things tonight, and think more about the rest.
> On 7/21/2010 5:25 PM, Peter Firmstone wrote:
>> Hi Patricia,
>> Instead of Task passing an Iterable<Task>, it could pass an
>> Enumerator<Task>, which is inherently immutable. One more comment 
>> inline.
> I assume you mean Enumeration<Task>? I prefer Iterable<Task> because 
> it allows for the enhanced for loop:


> public Task runAfter(Iterable<Task> candidates){
>   for(Task t: candidates){
>     if(this has to wait for t){
>       return t;
>     }
>   }
>   return null;
> }
> Given the number of TaskManager callers, I think there is value in
> keeping their code as clean and simple as possible.

Ok, didn't think of that, still using the old for loop.

> On 7/21/2010 6:25 PM, Peter Firmstone wrote:
> ....
> > I try to keep synchronized blocks as small as possible, not so much for
> > performance, but for bugs, not even necessarily my own bugs but client
> > code concurrency bugs. In the synchronized block, I don't call objects
> > which may be accessible from outside the object I'm calling from. State
> > that needs to be atomically updated, I group together using the same
> > lock, I also consider using the ReadWriteLock, if reads will outnumber
> > writes. If multiple objects must be updated atomically, I might group
> > them together into an encapsulating object with the methods I need to
> > make it atomic. This is better than holding multiple locks.
> >
> The most important concurrency issue in TaskManager is probably the
> runAfter testing. In a TaskManager with n existing tasks, a runAfter
> test is O(n). The only other O(n) operation is getPending, which I think
> is much less frequent. Everything else is, or can be, O(1) or O(log n).
> I've arranged the order to minimize the number of calls, by finding the
> youngest runAfter task first. However, I do not have a good solution to
> a task that might need to runAfter, but does not in fact need to
> runAfter any of the existing tasks. I just has to scan the whole list.
> Moreover, I have to call back to the runAfter method in the caller's
> Task object.
> I've thought about some ideas, but so far nothing really satisfactory.

That's a tough one, we may have to accept it, you've already got 
significantly improved performance over the original implementation.


> Patricia

View raw message