normal version of searching for a number in an array:
boolean search(int x, int[] arr) {
for (int i : arr) {
if (i == x) {
return true;
}
}
return false;
}
my way of multithreading it:
boolean searchAsync(int x, int[] arr, int lo, int hi) {
if (lo == hi) {
return x == arr[lo];
}
int mid = (lo hi) / 2;
CompletableFuture<Boolean> cf = CompletableFuture.<Boolean>supplyAsync(() -> searchAsync(x, arr, lo, mid));
boolean b = searchAsync(x, arr, mid 1, hi);
return cf.thenApply(a -> a | b).join();
}
boolean searchAsync(int x, int[] arr) {
return searchAsync(x, arr, 0, arr.length - 1);
}
but it doesn't return anything
CodePudding user response:
You could use parallel streams:
boolean search(int x, int[] arr) {
return Arrays.stream(arr).parallel()
.filter(i -> i == x)
.findAny()
.isPresent();
}
This way you don't have to deal with the low level mechanics of multithreading yourself.
CodePudding user response:
Multi-threading a purely CPU-bound task is often hard, as it is difficult to evaluate the overhead of thread synchronization and avoid computing too much.
For instance here, you wouldn’t want to check each entry in a separate task, as the overhead would be higher than the task itself. Moreover you will also want to stop the process as soon as possible, i.e. as quickly as possible after finding a match.
Fortunately, Java 8 also provides the Stream
API, which easily handles parallelism for CPU-bound tasks that involve a (large) collection of data, so your method implementation simply becomes:
boolean searchAsync(int x, int[] arr) {
return Arrays.stream(arr).parallel().anyMatch(i -> i == x);
}
(note that without the parallel()
it becomes purely equivalent to your first example with the for
loop)