javamultithreadingparallel-processingexecutorservicerunnable

Best approach to manage parallel threads with a set of ip addresses using ExecutorService


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


Solution

  • You can do something as follows:

    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();
            };
        }
    }