В основном я запускаю несколько потоков, которые снова запускают длительный процесс, который следует контролировать. В примере «длинные» запущенные процессы - это простые вызовы ping. IpListener несет ответственность за запуск событий, когда процесс завершается или завершается с ошибкой.Выполнение после ожидания событий нескольких потоков при сохранении запущенных процессов
Теперь идет интересная часть: каждый раз, когда ip находится на выходе консоли, запускается метод onIpFound. То, что я хочу сделать, - подождать, пока все потоки не найдут IP-адрес в первый раз, а затем продолжите выполнение основного метода. Однако запущенные процессы должны продолжать выполняться и в конечном итоге должны вызывать вышеупомянутые события onProcessEnd и onProcessFailure. Есть ли у вас какие-либо намеки для реализации этого поведения (звуковым образом)?
Вот часть небольшого примера приложения, чтобы дать вам лучшее понимание:
ReaderTest.java
package com.test;
public class ReaderTest {
public static void main(String[] args) {
IpReader ipReader = new IpReader("stackoverflow.com");
ipReader.setListener(new SimpleIpListener());
new Thread(ipReader).start();
IpReader ipReader2 = new IpReader("stackexchange.com");
ipReader2.setListener(new SimpleIpListener());
new Thread(ipReader2).start();
// TODO: start next step as soon as both ips are known
}
}
IpReader.java
package com.test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class IpReader implements Runnable {
private IpListener ipListener = null;
private String hostName;
public IpReader(String hostName) {
this.hostName = hostName;
}
public interface IpListener {
public void onIpFound(String ip);
public void onProcessEnd(String string);
public void onProcessFailure(String string);
}
public void setListener(IpListener ipListener) {
this.ipListener = ipListener;
}
@Override
public void run() {
// TODO Auto-generated method stub
ProcessBuilder pb = new ProcessBuilder().command("cmd", "/c", "ping", "-n", "10", hostName);
pb.redirectErrorStream(true);
Process process = null;
try {
try {
process = pb.start();
String line = null;
// print stream
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
while ((line = br.readLine()) != null) {
Pattern p = Pattern.compile("(?:[0-9]{1,3}\\.){3}[0-9]{1,3}");
Matcher m = p.matcher(line);
if (m.find()) {
// IPv4 found
if (ipListener != null) {
ipListener.onIpFound(m.group(0));
}
}
}
process.waitFor();
if (ipListener != null)
ipListener.onProcessEnd("Process END");
} finally {
if (process != null)
process.destroy();
}
} catch (InterruptedException | IOException e) {
if (ipListener != null)
ipListener.onProcessFailure("Process failure");
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
SimpleIpListener.java
package com.test;
import com.test.IpReader.IpListener;
public class SimpleIpListener implements IpListener {
private boolean ipFound = false;
@Override
public void onIpFound(String ip) {
if (!ipFound)
System.out.println("IP " + ip + " found.");
ipFound = true;
}
@Override
public void onProcessEnd(String string) {
System.out.println("Process ended.");
}
@Override
public void onProcessFailure(String string) {
System.out.println("Process failure");
}
}