我有一个简单的应用程序,我在一个类中创建 3 个线程来 ping 3 个不同的网站,并记下执行此操作所需的时间。
我希望通过查看 3 个线程中的哪一个首先成功执行并终止另外两个来增强它。
JDK 的哪个类对此有帮助?以及如何?
ping 网站的示例代码:
public static boolean pingUrl(final String address) {
try {
final URL url = new URL("http://" + address);
final HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
urlConn.setConnectTimeout(1000 * 10); // mTimeout is in seconds
final long startTime = System.currentTimeMillis();
urlConn.connect();
final long endTime = System.currentTimeMillis();
if (urlConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
System.out.println("Time (ms) : " + (endTime - startTime));
System.out.println("Ping to "+address +" was success");
return true;
}
} catch (final MalformedURLException e1) {
e1.printStackTrace();
} catch (final IOException e) {
e.printStackTrace();
}
return false;
}
最佳答案
I wish to enhance it by seeing which thread out of the 3 executes successfully first and terminating the other two .
我将结合使用 ExecutorService
和 ExecutorCompletionService
。然后,当第一个任务完成时从完成服务返回第一个 Future
时,您将在 ExecutorService
上调用 shutdownNow()
。
javadocs for ExecutorCompletionService
非常好,并展示了如何使用它。
// maybe you want 10 threads working on your tasks
ExecutorService threadPool = Executors.newFixedThreadPool(10);
CompletionService<Result> ecs
= new ExecutorCompletionService<Result>(threadPool);
for (Callable<Result> task : tasks) {
// submit your tasks to the completion service, they run in the thread-pool
ecs.submit(task);
}
// once you get one result
Future<Result> future = ecs.take();
// kill the rest of the tasks
threadPool.shutdownNow();
Result result = future.get();
// probably will need to close the thread connections, see below
// maybe call threadPool.awaitShutdown(...) here to wait for the others to die
此机制的唯一问题是这只会中断线程。在您的情况下,它们将被困在不可中断的 urlConn.connect();
中。一旦 ecs.take()
返回,您将必须重新运行您的任务并在 HttpURLConnection
上调用 disconnect()
仍在进行中。即使如此,我也不确定它是否会停止当前正在进行的连接。如果这不起作用,那么您可能需要改用 Apache HttpClient
或其他一些可以关闭的类,以阻止线程等待更长时间。
for (Callable<Result> task : tasks) {
// you'll need to do something like this
task.closeConnection();
}
就您而言,您的任务可能类似于:
public class MyPingTask implements Callable<Boolean> {
private String address;
public MyPingTask(String address) {
this.address = address;
}
public Boolean call() throws Exception {
// obviously the pingUrl code could go right here
return pingUrl(address);
}
}
这是Java tutorial on ExecutorService
以及相关的类。
关于java - 多个线程的并行执行和终止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21096212/