[concurrency-interest] some stupid questions

Rémi Forax forax at univ-mlv.fr
Wed Dec 19 12:44:48 EST 2007

Doug Lea a écrit :
> Thanks for the suggestions!
> Rémi Forax wrote:
>> First a remark,
>> in the doc of ForkJoinTask, you can see this sentence:
>> "The ForkJoinTask class is not directly subclassable outside of this 
>> package"
>> but the constructor is public ?
> An oversight. Thanks!
>> Else, why ||*ParallelArray 
>> <http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166ydocs/jsr166y/forkjoin/ParallelArray.html#ParallelArray%28jsr166y.forkjoin.ForkJoinExecutor,%20int,%20java.lang.Class%29> 
>> is not a List,
>> it provides get/set/size/iterator but if you want a list you need to 
>> create another object
>> using asList(). So basically, why he doesn't inherits from 
>> AbstractList (and implements RandomAccess) ?
> It will be. See the discussion on this a few months ago.
> To briefly recap, reformulating as List does better integrate
> with other collections, but has a few non-obvious aspects --
> mainly that parallelArray.add(x) and similar per-element operations
> cannot themselves be threadsafe, which is a little surprising.
Is the methods that are not thread safe are the ones that change the size of
the array ?
I see a ParallelArray as a List backed in an array, so get/set are ok
but not add/remove.

> But the pluses outweigh the minuses, so the next version will
> include all the corresponding adaptations to support List. I've sat
> on this pending a couple of algorithmic issues I haven't decided
> upon (for example whether/how to parallelize data movement for
> element shifts), but ought to put these on hold and implement
> correct but suboptimal ones to get this out.
>> *I don't like the fact *|*ParallelArray 
>> <http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166ydocs/jsr166y/forkjoin/ParallelArray.html#ParallelArray%28jsr166y.forkjoin.ForkJoinExecutor,%20int,%20T%5B%5D%29>*(ForkJoinExecutor 
>> <http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166ydocs/jsr166y/forkjoin/ParallelArray.html>[] 
>> sourceToCopy)|
>> perform a defensive copy and |*ParallelArray 
>> <http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166ydocs/jsr166y/forkjoin/ParallelArray.html#ParallelArray%28jsr166y.forkjoin.ForkJoinExecutor,%20T%5B%5D%29>*(ForkJoinExecutor 
>> [] handoff)
>> don't.
>> |*
>> Perhaps The constructor
>> *|*ParallelArray 
>> <http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166ydocs/jsr166y/forkjoin/ParallelArray.html#ParallelArray%28jsr166y.forkjoin.ForkJoinExecutor,%20T%5B%5D%29>*(ForkJoinExecutor 
>>  should be protected
>> and a static method "wrap" introduced.
> Do you think this would be enough less error-prone to bother doing?
> Bearing in mind that ParallelArrays will normally be large, and
> that copying is a sequential bottleneck (parallelizing copying is
> of limited value in practice), people will need to think about how
> much copying they are doing.
ok, so perhaps the wrong constructor is the other one:
<http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166ydocs/jsr166y/forkjoin/ForkJoinExecutor.html> executor, 
int size, T 
<http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166ydocs/jsr166y/forkjoin/ParallelArray.html>[] sourceToCopy)|.

It's a matter of consistency, i think it's not a good idea to have a way 
to create a ParallelArray with a constructor
that do a defensive copy and another one that do nothing. It's error prone.

About a possiblestatic method, because it has a name are, in my opinion, 
a static method is easier to understand than a constructor
(in an other way, a static method is not great if you allow subclasses).
>> |I  think all  replace* method  should be renamed  to  fill*  |like 
>> in java.util.Arrays.
>> ||And to be consistent, randomFill() should be fillRandom().
> We've at one point or another had this both ways. To me,
> the replace prefix sounds a little better.
> Other opinions are welcome though. Here's what they look like
> with the different prefixes:
>     void replaceWithCombination(ParallelArray<? extends T> other, 
> Ops.Reducer<T> combiner);
>     void replaceWithCombination(T[] other, Ops.Reducer<T> combiner);
>     void replaceWithGeneratedValue(Ops.Generator<? extends T> generator);
>     void replaceWithMappedIndex(Ops.MapperFromInt<? extends T> mapper);
>     void replaceWithTransform(Ops.Mapper<? super T,? extends T> mapper);
>     void replaceWithValue(T value);
i don't like "replace" because in my opinion it implictly refer to one 
so perhaps replaceAllWith* is better.
>     void fillWithCombination(ParallelArray<? extends T> other, 
> Ops.Reducer<T> combiner);
>     void fillWithCombination(T[] other, Ops.Reducer<T> combiner);
>     void fillWithGeneratedValue(Ops.Generator<? extends T> generator);
>     void fillWithMappedIndex(Ops.MapperFromInt<? extends T> mapper);
>     void fillWithTransform(Ops.Mapper<? super T,? extends T> mapper);
>     void fillWithValue(T value);
>> I wonder if ||*newArray 
>> <http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166ydocs/jsr166y/forkjoin/ParallelArray.WithFilter.html#newArray%28java.lang.Class%29>*(Class 
>> <http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true><? 
>> super T 
>> <http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166ydocs/jsr166y/forkjoin/ParallelArray.WithFilter.html>> 
>> elementType can't be rewritten to
>> <U> ParallelArray<U> newArray(Class<U> elementType) in order to allow 
>> upcasting
>> if possible and a ClassCastException otherwise.
> Thanks. You are right that it would be more consistent with other similar
> APIs to support this overloaded version.
> -Doug

More information about the Concurrency-interest mailing list