[concurrency-interest] private field

Doug Lea dl@cs.oswego.edu
Thu, 14 Oct 2004 07:42:16 -0400


>>Why fields in classes java.util.concurrent.* like LinkedBlockingQueue
>>are declared private instead of protected ?  It's very annoying.

As David said, the main reason is that JDK library classes really must
be written in a way that allows internals to be ripped out and
completely rewritten. (This happens fairly regularly, for example,
twice for the java.lang.ThreadLocal class.)

But it seems to me that you want a specialized version of ArrayList,
not LinkedBlockingQueue.

> I want to use very fast queue for the SEDA framework.  One 
> performance-critical method is to move all elements of the queue in a 
> array. 

Do you really nead an array? If you instead use ArrayList, it ought to
be acceptable to do:

  ArrayList c = new ArrayList(q.size());
  q.drainTo(c);

I suspect the performance difference between this and a custom
solution would be negligible.  The ArrayList will only occasionally
need to resize. To further reduce the likelihood at the expense of
some space overhead, you could create it with say 2*q.size() capacity.

The second array copy that would otherwise be needed for c.toArray()
is the main inefficiency here. If you really do need raw arrays, an
alternative is to make your own specialized version of ArrayList, say:

class TempArrayList extends AbstractCollection { // non-generic for simplicity
   Object[] elements;
   int count;
   TempArrayList(int size) { elements = new Object[size]; }
   boolean add(Object x) {
     if (count >= elements.length) resize();
     elements[count++] = x;
     return true;
   }
  Object[] getArray() { return elements; }
  // etc (not bothering to implement most optional Collection methods)
}

Where the getArray method returns the underlying array without
copying.  (You would need to be careful to use only the elements up
through elements[count], not the entire array though.)  You could also
make a constructor that accepts an existing array, so you can recyle
it.   Such a class would of course not otherwise be very useful,
but might avoid the need to make a custom queue subclass.

=Doug