I have a set of 255 ip addresses to manage (x.x.x.1 -> x.x.x.255).
In Java if I check connection from my java mobile app with only one array of IP with a setTimeout(200)
I could wait too much till finish all 255 ip addresses. On the other hand if I connect to at least one of those ip address I have some other things to do.
So my goal to reduce wait time on check if connection test works or fails is to split in a group of 15 parallel threads working at the same time where inside each of them I check 17 ip addresses.
In this way I made a class that implements Runnable where I execute something like:
HttpURLConnection con;
for(i=(currentThreadNumber*17) 1;i<(currentThreadNumber*17) 17;i ) {
String ipToCheckConnection = maskIP "." i;
String loginURL = "http://" ipToLogin "/....";
try {
URL obj = new URL(loginURL);
con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
con.setConnectTimeout(100);
con.connect();
int responseCode = con.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
con.disconnect();
do something else with this IP....
}
} catch (java.net.SocketTimeoutException e) {
continue;
} catch (java.io.IOException e) {
return;
}
}
In my main function inside a button click event I implement:
ExecutorService executorService = Executors.newFixedThreadPool(15);
then I tried various way to execute parallel jobs calling the runnable class waiting all threads are finished before to continue and exit from button click event, like using CountDownLatch
, .awaitTermination
... I tried also to use .invokeAll
but it doesn't work with runnable but with callable... but I encounter the issue how to pass to runnable class current thread count like 0,1,2,3,..so I can pass to the for(...)
inside runnable...
What would be best approach to pass this current thread count like 0,1,2,3,.. to the runnable class?
Or is there a better different way than using ExecutorService which I read everywhere it's the simplest way to work parallel threads with?...
Thanks! Cheers
CodePudding user response:
You can do something as follows:
- initialize the
CountDownLatch
andExecutorService
with the number of desired workers - on the loop of assigning work to the workers pass the current task number
- each worker should also call
countDownLatch.countDown();
after having terminated the work to signal that to the other workers that might be waiting - the main thread should call
countDownLatch.await();
to wait for the remaining workers to finish their work.
The code could look like the following:
public class WaitForAllToEnd {
public static void main(String[] args) throws InterruptedException {
final int total_threads = 15;
CountDownLatch countDownLatch = new CountDownLatch(total_threads);
ExecutorService executor = Executors.newFixedThreadPool(total_threads);
for(int i = 0; i < total_threads; i ){
final int thread_id = i;
executor.execute(parallelWork(thread_id, countDownLatch));
}
countDownLatch.await();
System.out.println("Exit");
executor.shutdown();
}
private static Runnable parallelWork(int thread_id, CountDownLatch countDownLatch) {
return () -> {
try {
// Some code logic
} catch (InterruptedException e) {
// Do Something
}
// Some code logic
countDownLatch.countDown();
};
}
}