/* package whatever; // don't place package name! */
import java.util.Random ;
import java.util.concurrent.ForkJoinPool ;
import java.util.concurrent.RecursiveTask ;
public class MaximumFinder extends RecursiveTask< Integer> {
private static final int SEQUENTIAL_THRESHOLD = 5 ;
private final int [ ] data;
private final int start;
private final int end;
public MaximumFinder( int [ ] data, int start, int end) {
this .data = data;
this .start = start;
this .end = end;
}
public MaximumFinder( int [ ] data) {
this ( data, 0 , data.length ) ;
}
@Override
final int length = end - start;
if ( length < SEQUENTIAL_THRESHOLD) {
return computeDirectly( ) ;
}
final int split = length / 2 ;
final MaximumFinder left = new MaximumFinder( data, start, start + split) ;
left.fork ( ) ;
final MaximumFinder right = new MaximumFinder( data, start + split, end) ;
return Math .
max ( right.
compute ( ) , left.
join ( ) ) ; }
private Integer computeDirectly
( ) { System .
out .
println ( Thread .
currentThread ( ) + " computing: " + start
+ " to " + end) ;
for ( int i = start; i < end; i++ ) {
if ( data[ i] > max) {
max = data[ i] ;
}
}
return max;
}
public static void main
( String [ ] args
) { // create a random data set
final int [ ] data = new int [ 1000 ] ;
for ( int i = 0 ; i < data.length ; i++ ) {
data[ i] = random.nextInt ( 100 ) ;
}
// submit the task to the pool
final ForkJoinPool pool = new ForkJoinPool( 4 ) ;
final MaximumFinder finder = new MaximumFinder( data) ;
System .
out .
println ( pool.
invoke ( finder
) ) ; }
}
LyogcGFja2FnZSB3aGF0ZXZlcjsgLy8gZG9uJ3QgcGxhY2UgcGFja2FnZSBuYW1lISAqLwppbXBvcnQgamF2YS51dGlsLlJhbmRvbTsgCmltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5Gb3JrSm9pblBvb2w7IAppbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuUmVjdXJzaXZlVGFzazsgCiAgCnB1YmxpYyBjbGFzcyBNYXhpbXVtRmluZGVyIGV4dGVuZHMgUmVjdXJzaXZlVGFzazxJbnRlZ2VyPiB7IAogIAogIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTRVFVRU5USUFMX1RIUkVTSE9MRCA9IDU7IAogIAogIHByaXZhdGUgZmluYWwgaW50W10gZGF0YTsgCiAgcHJpdmF0ZSBmaW5hbCBpbnQgc3RhcnQ7IAogIHByaXZhdGUgZmluYWwgaW50IGVuZDsgCiAgCiAgcHVibGljIE1heGltdW1GaW5kZXIoaW50W10gZGF0YSwgaW50IHN0YXJ0LCBpbnQgZW5kKSB7IAogICAgdGhpcy5kYXRhID0gZGF0YTsgCiAgICB0aGlzLnN0YXJ0ID0gc3RhcnQ7IAogICAgdGhpcy5lbmQgPSBlbmQ7IAogIH0gCiAgCiAgcHVibGljIE1heGltdW1GaW5kZXIoaW50W10gZGF0YSkgeyAKICAgIHRoaXMoZGF0YSwgMCwgZGF0YS5sZW5ndGgpOyAKICB9IAogIAogIEBPdmVycmlkZQogIHByb3RlY3RlZCBJbnRlZ2VyIGNvbXB1dGUoKSB7IAogICAgZmluYWwgaW50IGxlbmd0aCA9IGVuZCAtIHN0YXJ0OyAKICAgIGlmIChsZW5ndGggPCBTRVFVRU5USUFMX1RIUkVTSE9MRCkgeyAKICAgICAgcmV0dXJuIGNvbXB1dGVEaXJlY3RseSgpOyAKICAgIH0gCiAgICBmaW5hbCBpbnQgc3BsaXQgPSBsZW5ndGggLyAyOyAKICAgIGZpbmFsIE1heGltdW1GaW5kZXIgbGVmdCA9IG5ldyBNYXhpbXVtRmluZGVyKGRhdGEsIHN0YXJ0LCBzdGFydCArIHNwbGl0KTsgCiAgICBsZWZ0LmZvcmsoKTsgCiAgICBmaW5hbCBNYXhpbXVtRmluZGVyIHJpZ2h0ID0gbmV3IE1heGltdW1GaW5kZXIoZGF0YSwgc3RhcnQgKyBzcGxpdCwgZW5kKTsgCiAgICByZXR1cm4gTWF0aC5tYXgocmlnaHQuY29tcHV0ZSgpLCBsZWZ0LmpvaW4oKSk7IAogIH0gCiAgCiAgcHJpdmF0ZSBJbnRlZ2VyIGNvbXB1dGVEaXJlY3RseSgpIHsgCiAgICBTeXN0ZW0ub3V0LnByaW50bG4oVGhyZWFkLmN1cnJlbnRUaHJlYWQoKSArICIgY29tcHV0aW5nOiAiICsgc3RhcnQgCiAgICAgICAgICAgICAgICAgICAgICAgKyAiIHRvICIgKyBlbmQpOyAKICAgIGludCBtYXggPSBJbnRlZ2VyLk1JTl9WQUxVRTsgCiAgICBmb3IgKGludCBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykgeyAKICAgICAgaWYgKGRhdGFbaV0gPiBtYXgpIHsgCiAgICAgICAgbWF4ID0gZGF0YVtpXTsgCiAgICAgIH0gCiAgICB9IAogICAgcmV0dXJuIG1heDsgCiAgfSAKICAKICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7IAogICAgLy8gY3JlYXRlIGEgcmFuZG9tIGRhdGEgc2V0IAogICAgZmluYWwgaW50W10gZGF0YSA9IG5ldyBpbnRbMTAwMF07IAogICAgZmluYWwgUmFuZG9tIHJhbmRvbSA9IG5ldyBSYW5kb20oKTsgCiAgICBmb3IgKGludCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspIHsgCiAgICAgIGRhdGFbaV0gPSByYW5kb20ubmV4dEludCgxMDApOyAKICAgIH0gCiAgCiAgICAvLyBzdWJtaXQgdGhlIHRhc2sgdG8gdGhlIHBvb2wgCiAgICBmaW5hbCBGb3JrSm9pblBvb2wgcG9vbCA9IG5ldyBGb3JrSm9pblBvb2woNCk7IAogICAgZmluYWwgTWF4aW11bUZpbmRlciBmaW5kZXIgPSBuZXcgTWF4aW11bUZpbmRlcihkYXRhKTsgCiAgICBTeXN0ZW0ub3V0LnByaW50bG4ocG9vbC5pbnZva2UoZmluZGVyKSk7IAogIH0gCn0K