I have a program which sends a ping request to the servers. The list is large and if an IP
is unreachable it takes time to go to the next IP
.
I wish that, for every IP
, it should create a new thread & process all of them simultaneously.
Here is the code:
for (int i = 0; i < 89; i++)
{
ProcessBuilder processBuilder = new ProcessBuilder("ping", isWindows? "-n" : "-c", "1", buttons[i].getText());
Process proc = processBuilder.start();
returnVal = proc.waitFor();
}
How can I make this code to ping all IP
s, each in a separate thread ?
How about doing without ProcessBuilder
as suggested by others also.
I have three classes - PingParallel
is my main class, PingTask
is the task performed by each thread, and PingResult
is having result code (we can add some more info also, status message etc.).
PingParallel
package com.test.thread;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class PingParallel {
public static void main(String[] args) {
int totalIps = 89;
ExecutorService executor = Executors.newFixedThreadPool(totalIps);
List<Future<PingResult>> list = new ArrayList<Future<PingResult>>();
Callable<PingResult> callable = null;
for(int i=0; i< totalIps; i++){
callable = new PingTask("127.0.0"+i); // Get the ipAddres buttons[i].getText());
Future<PingResult> future = executor.submit(callable);
list.add(future);
}
for(Future<PingResult> fut : list){
try {
System.out.println(new Date()+ "::"+fut.get());
} catch (Exception e) {
e.printStackTrace();
}
}
executor.shutdown();
}
}
PingTask
package com.test.thread;
import java.net.InetAddress;
import java.util.concurrent.Callable;
public class PingTask implements Callable<PingResult> {
private String ipAddress;
public PingTask(String ipAddress) {
this.ipAddress = ipAddress;
}
@Override
public PingResult call() {
InetAddress inet = null;
try {
inet = InetAddress.getByName(ipAddress);
int resultCode = inet.isReachable(5000) ? 0 : -1;
return new PingResult(ipAddress, resultCode);
} catch (Exception e) {
e.printStackTrace();
return new PingResult(ipAddress, -1);
}
}
}
PingResult
package com.test.thread;
public class PingResult {
private String ipAddress;
private int resultCode;
public PingResult(String ipAddress, int resultCode) {
this.ipAddress = ipAddress;
this.resultCode = resultCode;
}
public String getIpAddress() {
return ipAddress;
}
public int getResultCode() {
return resultCode;
}
public String toString() {
return "IpAddress :: "+ ipAddress + " Result Code : "+ resultCode;
}
}
ProcessBuilder does invoke a new process, but you are effectively killing the parallelism by calling waitFor, since that will wait for the first process to complete before launching the next, making the calls sequential instead. You could either use PB and skip the wait calls, or perhaps use ordinary java threads wrapping calls to Runtime.exec instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With