/** * Combine this array reduction variable at the given index with the given value using the given * operation. (This array <TT>[i]</TT>) is set to (this array <TT>[i]</TT>) <I>op</I> * (<TT>value</TT>), then (this array <TT>[i]</TT>) is returned. * * @param i Index. * @param value Value. * @param op Binary operation. * @return (This array <TT>[i]</TT>) <I>op</I> (<TT>value</TT>). */ public T reduce(int i, T value, ObjectOp<T> op) { for (; ; ) { T oldvalue = myArray.get(i); T newvalue = op.op(oldvalue, value); if (myArray.compareAndSet(i, oldvalue, newvalue)) return newvalue; } }
/** * Combine a portion of this array reduction variable with a portion of the given array using the * given operation. For each index <TT>i</TT> from 0 to <TT>len</TT>-1, (this array * <TT>[dstoff+i]</TT>) is set to (this array <TT>[dstoff+i]</TT>) <I>op</I> * (<TT>src[srcoff+i]</TT>). * * <p>The <TT>reduce()</TT> method is multiple thread safe <I>on a per-element basis.</I> Each * individual array element is updated atomically, but the array as a whole is not updated * atomically. * * @param dstoff Index of first element to update in this array. * @param src Source array. * @param srcoff Index of first element to update from in the source array. * @param len Number of array elements to update. * @param op Binary operation. * @exception NullPointerException (unchecked exception) Thrown if <TT>src</TT> is null. Thrown if * <TT>op</TT> is null. * @exception IndexOutOfBoundsException (unchecked exception) Thrown if <TT>len</TT> < 0. * Thrown if any array index would be out of bounds. */ public void reduce(int dstoff, T[] src, int srcoff, int len, ObjectOp<T> op) { if (len < 0 || dstoff < 0 || dstoff + len > myArray.length() || srcoff < 0 || srcoff + len > src.length) { throw new IndexOutOfBoundsException(); } while (len > 0) { updateLoop: for (; ; ) { T oldvalue = myArray.get(dstoff); T newvalue = op.op(oldvalue, src[srcoff]); if (myArray.compareAndSet(dstoff, oldvalue, newvalue)) break updateLoop; } ++dstoff; ++srcoff; --len; } }