river-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Patricia Shanahan <p...@acm.org>
Subject Re: TaskManager progress
Date Thu, 22 Jul 2010 05:25:03 GMT
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.

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.


View raw message