I am trying something similar to Search for an element in array with threads. Instead of using an actual array, the target value will be between 0
and Integer.MAX_VALUE * 10L
and the goal is to find that target through the usage of a simple for loop.
- The
Searcher
class will be the thread itself. Note the condition of the for loop which isi <= endIndex && Starter.running.get()
. - The
Starter
will create the threads and take care of initializing everything else.
There is AtomicBoolean
variable type named running
used to ensure threads stop execution when one of them find the element. The issue is that the the multithreaded approach takes twice the time compared to the single-threaded one. Without running
, the multithreaded code will take even longer.
My goal is to stop all the threads when the target is found and know whether or not the target is found. Of course, if the target isn't in range, then the threads will have to check the entire segment and not find anything.
Sample output:
Target is: 15794437641
Multithreaded option has now started...
Found target using multithreading: 15794437641
Found!
Multithreaded time: 00h:00m:08s.714
Multithreaded option has now completed.
Single thread option has now started...
Found target using single thread: 15794437641
Single thread time: 00h:00m:04s.226
Single thread option has now completed...
The entire code:
import java.util.concurrent.atomic.AtomicBoolean;
class Searcher implements Runnable {
private long target;
private long startIndex;
private long endIndex;
private long range;
public Searcher(long target, long startIndex, long endIndex, long range) {
this.target = target;
this.startIndex = startIndex;
this.endIndex = endIndex;
this.range = range;
}
public void run() {
for (long i = startIndex; i <= endIndex && Starter.running.get(); i++) {
if (i == target) {
Starter.running.set(false);
Starter.isFound.set(true);
System.out.println("Found target using multithreading: " + i);
Thread.currentThread().interrupt();
}
}
}
}
public class Starter {
public static final AtomicBoolean running = new AtomicBoolean(true);
public static final AtomicBoolean isFound = new AtomicBoolean(false);
private static void findElementMultithreaded(
int threadNumber, long target, long range
) {
Thread[] threads = new Thread[threadNumber];//store threads created
long segment = range / threadNumber;
//create the threads but don't start them yet
for (int i = 0; i <= threadNumber - 1; i++) {
Searcher s;
Thread t;
long start = i * range;
long end = range - 1;
if (i == threadNumber - 1) {
s = new Searcher(target, start, end, segment);
} else {
s = new Searcher(target, start, start + end, segment);
}
t = new Thread(s);
threads[i] = t;
}
//start all threads
for (Thread t : threads) {
t.start();
}
//join all threads
for (Thread t : threads) {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private static void findElementSingleThread(long target, long size) {
for (long i = 0; i < size; i++) {
if (i == target) {
System.out.println("Found target using single thread: " + i);
break;
}
}
}
public static String getLapsedTime(long start, long end) {
long t = end - start;
long millis = t % 1000;
long x = t / 1000;
long seconds = x % 60;
x /= 60;
long minutes = x % 60;
x /= 60;
long hours = x % 24;
return String.format(
"%02dh:%02dm:%02ds.%03d", hours, minutes, seconds, millis
);
}
public static void main(String[] args) {
int numberOfThreads = 8;
long size = Integer.MAX_VALUE * 10L;
long target = (long) (Math.random() * size);
System.out.println("Target is: " + target);
long start;
long end;
System.out.println("Multithreaded option has now started...");
start = System.currentTimeMillis();
findElementMultithreaded(numberOfThreads, target, size);
if (isFound.get()) {
System.out.println("Found!");
}
end = System.currentTimeMillis();
System.out.println("Multithreaded time: " + getLapsedTime(start, end));
System.out.println("Multithreaded option has now completed.\n");
//
System.out.println("Single thread option has now started...");
start = System.currentTimeMillis();
findElementSingleThread(target, size);
end = System.currentTimeMillis();
System.out.println("Single thread time: " + getLapsedTime(start, end));
System.out.println("Single thread option has now completed...");
}
}