import java.util.List ;
import java.util.concurrent.ForkJoinPool ;
import java.util.concurrent.ForkJoinTask ;
import java.util.concurrent.RecursiveTask ;
class Ideone
{
public static void main
( String [ ] args
) { // 2 active workers
ForkJoinPool pool = new ForkJoinPool( 2 ) ;
// whatever many elements in the list
List
< Integer
> original
= List .
of ( 1 ,
2 ,
3 ,
4 ,
5 ,
6 ,
7 ,
8 ,
9 ,
10 ,
11 ,
12 ,
13 ,
14 ,
15 ,
16 ,
17 ,
18 ,
19 ) ;
// main task will split up the list into sub threads
int result = pool.invoke ( new ParallelSum( original, 0 , original.size ( ) ) ) ;
System .
out .
println ( "Expected Result: " + original.
stream ( ) .
mapToInt ( Integer :: intValue
) .
sum ( ) ) ; System .
out .
println ( "Actual Result: " + result
) ; }
static class ParallelSum extends RecursiveTask< Integer> {
private static final int THRESHOLD = 4 ;
private final List< Integer> ints;
private final int offset, batchSize;
ParallelSum( List< Integer> ints, int offset, int batchSize) {
this .ints = ints;
this .offset = offset;
this .batchSize = batchSize;
}
@Override
if ( batchSize <= THRESHOLD) {
// process this batch
int sum = 0 ;
for ( int i = 0 ; i < batchSize; i++ ) {
sum += ints.get ( offset + i) ;
}
System .
out .
println ( Thread .
currentThread ( ) .
getName ( ) + " processed batch of size: " + batchSize
+ " from offset: " + offset
+ " and got sum: " + sum
) ; return sum;
} else {
// divide and conquer
int newLength = batchSize / 2 ;
new ParallelSum( ints, offset, newLength) ,
// the `bitwise and` helps us to divide odd number of tasks
new ParallelSum( ints, offset + newLength, newLength + ( batchSize & 1 ) )
) ;
return ForkJoinTask.invokeAll ( tasks)
.stream ( )
.mapToInt ( ForkJoinTask:: join)
.sum ( ) ;
}
}
}
}
aW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRm9ya0pvaW5Qb29sOwppbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRm9ya0pvaW5UYXNrOwppbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuUmVjdXJzaXZlVGFzazsKCmNsYXNzIElkZW9uZQp7CiAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CiAgICAgICAgLy8gMiBhY3RpdmUgd29ya2VycwogICAgICAgIEZvcmtKb2luUG9vbCBwb29sID0gbmV3IEZvcmtKb2luUG9vbCgyKTsKCiAgICAgICAgLy8gd2hhdGV2ZXIgbWFueSBlbGVtZW50cyBpbiB0aGUgbGlzdAogICAgICAgIExpc3Q8SW50ZWdlcj4gb3JpZ2luYWwgPSBMaXN0Lm9mKDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTUsIDE2LCAxNywgMTgsIDE5KTsKCiAgICAgICAgLy8gbWFpbiB0YXNrIHdpbGwgc3BsaXQgdXAgdGhlIGxpc3QgaW50byBzdWIgdGhyZWFkcwogICAgICAgIGludCByZXN1bHQgPSBwb29sLmludm9rZShuZXcgUGFyYWxsZWxTdW0ob3JpZ2luYWwsIDAsIG9yaWdpbmFsLnNpemUoKSkpOwogICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRXhwZWN0ZWQgUmVzdWx0OiAiICsgb3JpZ2luYWwuc3RyZWFtKCkubWFwVG9JbnQoSW50ZWdlcjo6aW50VmFsdWUpLnN1bSgpKTsKICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkFjdHVhbCBSZXN1bHQ6ICAgIiArIHJlc3VsdCk7CiAgICB9CgogICAgc3RhdGljIGNsYXNzIFBhcmFsbGVsU3VtIGV4dGVuZHMgUmVjdXJzaXZlVGFzazxJbnRlZ2VyPiB7CiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFRIUkVTSE9MRCA9IDQ7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBMaXN0PEludGVnZXI+IGludHM7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgb2Zmc2V0LCBiYXRjaFNpemU7CgogICAgICAgIFBhcmFsbGVsU3VtKExpc3Q8SW50ZWdlcj4gaW50cywgaW50IG9mZnNldCwgaW50IGJhdGNoU2l6ZSkgewogICAgICAgICAgICB0aGlzLmludHMgPSBpbnRzOwogICAgICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDsKICAgICAgICAgICAgdGhpcy5iYXRjaFNpemUgPSBiYXRjaFNpemU7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgSW50ZWdlciBjb21wdXRlKCkgewogICAgICAgICAgICBpZiAoYmF0Y2hTaXplIDw9IFRIUkVTSE9MRCkgewogICAgICAgICAgICAgICAgLy8gcHJvY2VzcyB0aGlzIGJhdGNoCiAgICAgICAgICAgICAgICBpbnQgc3VtID0gMDsKICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYmF0Y2hTaXplOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICBzdW0gKz0gaW50cy5nZXQob2Zmc2V0ICsgaSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXROYW1lKCkgKyAiIHByb2Nlc3NlZCBiYXRjaCBvZiBzaXplOiAiICsgYmF0Y2hTaXplICsgIiBmcm9tIG9mZnNldDogIiArIG9mZnNldCArICIgYW5kIGdvdCBzdW06ICIgKyBzdW0pOwogICAgICAgICAgICAgICAgcmV0dXJuIHN1bTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIGRpdmlkZSBhbmQgY29ucXVlcgogICAgICAgICAgICAgICAgaW50IG5ld0xlbmd0aCA9IGJhdGNoU2l6ZSAvIDI7CiAgICAgICAgICAgICAgICB2YXIgdGFza3MgPSBMaXN0Lm9mKAogICAgICAgICAgICAgICAgICAgIG5ldyBQYXJhbGxlbFN1bShpbnRzLCBvZmZzZXQsIG5ld0xlbmd0aCksCiAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGBiaXR3aXNlIGFuZGAgaGVscHMgdXMgdG8gZGl2aWRlIG9kZCBudW1iZXIgb2YgdGFza3MKICAgICAgICAgICAgICAgICAgICBuZXcgUGFyYWxsZWxTdW0oaW50cywgb2Zmc2V0ICsgbmV3TGVuZ3RoLCBuZXdMZW5ndGggKyAoYmF0Y2hTaXplICYgMSkpCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgcmV0dXJuIEZvcmtKb2luVGFzay5pbnZva2VBbGwodGFza3MpCiAgICAgICAgICAgICAgICAgICAgLnN0cmVhbSgpCiAgICAgICAgICAgICAgICAgICAgLm1hcFRvSW50KEZvcmtKb2luVGFzazo6am9pbikKICAgICAgICAgICAgICAgICAgICAuc3VtKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0=