/** * Combine a portion of this matrix reduction variable with a portion of the given matrix using * the given operation. For each row index <TT>r</TT> from 0 to <TT>rowlen-1</TT> inclusive, and * for each column index <TT>c</TT> from 0 to <TT>collen-1</TT> inclusive, (this matrix * <TT>[dstrow+r,dstcol+c]</TT>) is set to (this matrix <TT>[dstrow+r,dstcol+c]</TT>) <I>op</I> * (<TT>src[srcrow+r,srccol+c]</TT>). * * <p>The <TT>reduce()</TT> method is multiple thread safe <I>on a per-element basis.</I> Each * individual matrix element is updated atomically, but the matrix as a whole is not updated * atomically. * * @param dstrow Row index of first element to update in this matrix. * @param dstcol Column index of first element to update in this matrix. * @param src Source matrix. * @param srcrow Row index of first element to update from in the source matrix. * @param srccol Column index of first element to update from in the source matrix. * @param rowlen Number of rows to update. * @param collen Number of columns 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>rowlen</TT> < 0. * Thrown if <TT>collen</TT> < 0. Thrown if any matrix index would be out of bounds. */ public void reduce( int dstrow, int dstcol, long[][] src, int srcrow, int srccol, int rowlen, int collen, LongOp op) { if (rowlen < 0 || collen < 0 || dstrow < 0 || dstrow + rowlen > rows() || dstcol < 0 || dstcol + collen > cols() || srcrow < 0 || srcrow + rowlen > src.length || srccol < 0 || srccol + collen > src[0].length) { throw new IndexOutOfBoundsException(); } for (int r = 0; r < rowlen; ++r) { AtomicLongArray myMatrix_r = myMatrix[dstrow + r]; long[] src_r = src[srcrow + r]; for (int c = 0; c < collen; ++c) { int dstcol_c = dstcol + c; long src_r_c = src_r[srccol + c]; updateLoop: for (; ; ) { long oldvalue = myMatrix_r.get(dstcol_c); long newvalue = op.op(oldvalue, src_r_c); if (myMatrix_r.compareAndSet(dstcol_c, oldvalue, newvalue)) break updateLoop; } } } }
/** * @param product * @param sequence * @return false if there is an error */ boolean consume(S product, long sequence, long sleep) { if (product == null) return true; // make copies Consumer<S>[] consumers = this.consumers; AtomicLongArray outUse = this.outUse; long[] consumerSeqs = this.consumerSeqs; if (outUse.length() != consumers.length) return false; for (int j = 0; j < consumers.length; j++) { if (!consumers[j].isConsuming()) continue; long time = System.nanoTime(); if (!outUse.compareAndSet(j, 0, time)) continue; try { if (sequence <= consumerSeqs[j]) { outUse.lazySet(j, 0); if (outUse != this.outUse) resetConsumer(consumers[j]); break; } consumerSeqs[j] = sequence; consumers[j].consume(product, time); if (sleep > 0) Thread.sleep(sleep); outUse.lazySet(j, 0); if (outUse != this.outUse) { resetConsumer(consumers[j]); break; } } catch (Exception e) { if (listener == null) logger.error("consume", e); else listener.exceptionThrown(e); } } finishConsuming(product, sequence); return true; }
/** * Combine this matrix reduction variable at the given row and column with the given value using * the given operation. (This matrix <TT>[r,c]</TT>) is set to (this matrix <TT>[r,c]</TT>) * <I>op</I> (<TT>value</TT>), then (this matrix <TT>[r,c]</TT>) is returned. * * @param r Row index. * @param c Column index. * @param value Value. * @param op Binary operation. * @return (This matrix <TT>[r,c]</TT>) <I>op</I> (<TT>value</TT>). */ public long reduce(int r, int c, long value, LongOp op) { AtomicLongArray myMatrix_r = myMatrix[r]; for (; ; ) { long oldvalue = myMatrix_r.get(c); long newvalue = op.op(oldvalue, value); if (myMatrix_r.compareAndSet(c, oldvalue, newvalue)) { return newvalue; } } }