gpt4 book ai didi

java - 多线程ArrayList迭代

转载 作者:太空宇宙 更新时间:2023-11-04 06:25:35 25 4
gpt4 key购买 nike

问候!

我正在用 Java(JavaFX8) 编写一个简单的服务器监控应用程序。当前的实现能够一台一台地 ping 目标机器,并将它们绘制到 JavaFX LineChart 上。每台机器都是一个“目标”对象,保存在 ArrayList(可观察)中。我的问题是“一一”部分。 ping 目标的代码是返回 ping 的 Callable。不知何故,我需要对进程进行多线程处理,以便我可以一次至少对四个目标执行 ping 操作。过去的尝试导致了一些奇怪的情况,例如四个线程同时 ping 同一目标,从而导致非常毫无意义的处理器密集冗余。这是我当前的循环...

public void beginPing() {
ExecutorService exec = Executors.newCachedThreadPool();

Runnable r = new Runnable() {
@Override
public void run() {
while (true) {
for (Target t : targets) {
String ping = null;
if (t.flagsProperty().get().contains("A")) {
try {
Callable c = new Pinger(t);
ping = c.call().toString();
switch (ping) {
case "TIME_OUT":
for (XYChart.Series s : lineChart.getData()) {
if (s.getName().equals(t.nameProperty().get())) {
addToChart(s, cycle, 00.00);
}
}
t.setStatus("TIME OUT");
t.setLastrtt("TIME_OUT");
t.setTimeouts(t.timeoutsProperty().get() + 1);
logUtil.log(LogUtil.INFO, t.nameProperty().get() + " - timed out!");
break;
case "UNKNOWN_HOST":
t.setStatus("ERROR");
t.setLastrtt("UNKNOWN HOST");
logUtil.log(LogUtil.WARNING, t.nameProperty().get() + " - unknown host!");
break;
case "UNREACHABLE":
t.setStatus("ERROR");
t.setLastrtt("UNREACHABLE HOST");
logUtil.log(LogUtil.WARNING, t.nameProperty().get() + " - is unreachable!");
break;
default:
t.setLastrtt(ping);
t.setStatus("ACTIVE");
for (XYChart.Series s : lineChart.getData()) {
if (s.getName().equals(t.nameProperty().get())) {
addToChart(s, cycle, Double.valueOf(ping));
}
}
break;
}
} catch (Exception e) {
logUtil.log(LogUtil.CRITICAL, e.getMessage() + ", "+ e.getCause());
e.printStackTrace();
}
}
}
cycle++;
rangeChart(cycle);
updateInfo();
}
}
};
exec.execute(r);
}

最佳答案

我的印象是,您像普通类一样滥用 Callable 类 Pinger,尽管它只是一个不实现任何多线程服务的接口(interface)。你想做的事情应该看起来更像这样:

//init
Future<String> futures = new Future[targets.length];
String results = new String[targets.length];
ExecutorService service = Executors.newCachedThreadPool();

//start Threads
for (int i = 0; i<targets.length; i++){
Pinger pinger= new Pinger(targets[i]);
future[i] = service.submit(pinger);
}

//wait for Threads to finish and get results
for(int i = 0; i<futures.length; i++)
results[i] = futures[i].get()

您的 Pinger 应该如下所示:

public class Pinger implements Callable<String>{
Pinger(Target target){ ... }
public String call(){ ... }
}

在这里你可以找到一个完全实现的 Example for Callables 。在您的代码中,您只向 ExecutorService 提交一个 Runnable,因此只有两个线程(Main 和您的 Runnable)。您永远不会调用方法 call(),这是由 ExecutorService 完成的。与 Runnable Interface 相比,您必须调用 start 来执行线程或将其提交给 ExecutorService,而不是调用 run();您使用在提交()期间返回的Future。只要尝试理解 Callable 的概念,然后您就可以编写您想要的任何内容。 ;-)

关于java - 多线程ArrayList迭代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26838830/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com