You may use the good old Java's ThreadPoolExecutor.
Before I start, I suggest your read the other answers and comments, which pointed out useful data structures that should improve your search function without the need of multithreading utilities.
As @Xenolion mentioned, if you load your contacts from a database, consider querying directly into it without blocking your UI Thread.
If you go with the ThreadPoolExecutor
, you are basically dividing your Array
into smaller chunks that will each be processed by a Thread
.
You can find an exhaustive example in the Android Docs.
You'll need to implement a Runnable class that will be assigned a partition of your data.
class Worker implements Runnable {
// ...
public Worker(final Contact[] data, final int start, final int end) {
// have your workers hold a reference to the data array
this.data = data;
// ...
}
@Override public void run() {
for (int i = this.start, i < this.end; i++) {
if (this.data[i].contains(....) || ...) {
this.notifySearchEnded(i);
break;
}
}
// found nothing...
}
private void notifySearchEnded(final int index) {
// do whatever you want with the contact
log("Runnable " + this.id + " has found the contact at index " + index);
// hold somehow a reference to the executor
EXECUTOR.shutdown(); // tell the executor to stop the other threads
}
}
You'll then instantiate your ExecutorService and execute your Worker Threads
.
private static final int CORES = Runtime.getRuntime().availableProcessors();
public static final ExecutorService EXECUTOR = Executors.newFixedThreadPool(CORES);
Split your array into smaller chunks.
final int dataSize = data.lenght; // let's say 76'513
final int step = (int) (dataSize / CORES); // 76'513 / 4 = 19128
for (int i = 0; i < CORES; i++) {
final int start = i * step;
// give the left-over data to the last thread
final int end = (i == (CORES - 1)) ? (dataSize - 1) : (start + step - 1);
EXECUTOR.execute(new Worker(this.data, start, end));
}
My example isn't very efficient though. The Android link mentioned above contains a better example which makes use of a dynamic number of thread and a timeout for the executor. Take my example as a basis and follow the docs for an optimized version.
More examples, here and (with Futures), here and here: