public static void loopBlocks(int start , int endExclusive , int minBlock,
								  IntRangeConsumer consumer ) {
		final ForkJoinPool pool = BoofConcurrency.pool;
		int numThreads = pool.getParallelism();

		int range = endExclusive-start;
		if( range == 0 ) // nothing to do here!
			return;
		if( range < 0 )
			throw new IllegalArgumentException("end must be more than start. "+start+" -> "+endExclusive);

		int block = selectBlockSize(range,minBlock,numThreads);

		try {
			pool.submit(new IntRangeTask(start,endExclusive,block,consumer)).get();
		} catch (InterruptedException | ExecutionException e) {
			e.printStackTrace();
		}
	}
public static void loopBlocks ( int start , int endExclusive , int minBlock , IntRangeConsumer consumer ) { final ForkJoinPool pool = BoofConcurrency . pool ; int numThreads = pool . getParallelism ( ) ; int range = endExclusive - start ; if ( range == 0 ) return ; if ( range < 0 ) throw new IllegalArgumentException ( "end must be more than start. " + start + " -> " + endExclusive ) ; int block = selectBlockSize ( range , minBlock , numThreads ) ; try { pool . submit ( new IntRangeTask ( start , endExclusive , block , consumer ) ) . get ( ) ; } catch ( InterruptedException | ExecutionException e ) { e . printStackTrace ( ) ; } }
Automatically breaks the problem up into blocks based on the number of threads available. It is assumed
that there is some cost associated with processing a block and the number of blocks is minimized.

Examples:
<ul>
<li>Given a range of 0 to 100, and minBlock is 5, and 10 threads. Blocks will be size 10.</li>
<li>Given a range of 0 to 100, and minBlock is 20, and 10 threads. Blocks will be size 20.</li>
<li>Given a range of 0 to 100, and minBlock is 15, and 10 threads. Blocks will be size 16 and 20.</li>
<li>Given a range of 0 to 100, and minBlock is 80, and 10 threads. Blocks will be size 100.</li>
</ul>

@param start First index, inclusive
@param endExclusive Last index, exclusive
@param minBlock Minimum size of a block
@param consumer The consumer