【发布时间】:2018-05-02 07:10:53
【问题描述】:
我正在使用一个新线程来搜索服务器,而不是在其他类(如图形等)中产生任何滞后。我发现服务器 ArrayList 的 .add() 方法不起作用,甚至servers.size() 在新线程中不起作用。你知道发生了什么以及如何解决这个问题吗?
ArrayList<String> findServers(int howMany){
ArrayList<String> servers = new ArrayList<>();
Main.chatGraphics.log("<font face='arial' color='yellow'>Searching for servers...</font>");
Main.chatGraphics.msgInputTF.setText("Wait...");
Main.chatGraphics.msgInputTF.setEnabled(false);
new Thread(() -> {
Socket newSocket;
for (int i = 2; i < 254; i++){
if (servers.size() >= howMany)
break;
try {
newSocket = new Socket();
InetSocketAddress isa = new InetSocketAddress("192.168.1." + i, Main.DEFAULT_PORT);
if (isa.isUnresolved())
continue;
newSocket.connect(isa, 10);
servers.add(newSocket.getInetAddress().getHostAddress()); // DOESN'T WORK <<
} catch (Exception e) {
e.getStackTrace();
}
}
if (servers.size() == 0) // DOESN'T WORK TOO <<
Main.chatGraphics.log("<font face='arial' color='red'>No available servers</font>");
Main.chatGraphics.msgInputTF.setEnabled(true);
Main.chatGraphics.msgInputTF.setText("");
Main.chatGraphics.msgInputTF.grabFocus();
}).start();
return servers;
}
另外,这段代码还有另一个问题:Main.chatGraphics.msgInputTF.setText("Wait...") 不起作用。 setText 方法本身并不能仅在此方法中起作用。我认为这是因为 setEnabled(false) 方法紧随其后,但我不确定。你也可以帮我解决这个问题吗?
【问题讨论】:
-
请定义“不起作用”。您确实知道 1) 您的 servers 变量应该是
volatile,并且 2) 您在线程有机会对其执行任何操作之前返回了 servers 变量,您根本不应该返回它,而是在回调机制中使用它,例如可通过 SwingWorker 或 Callable(不是 Runnable)获得。 -
此外,这个
Main.chatGraphics.msgInputTF.setEnabled(true);不应在后台线程中调用,因为它违反了 Swing 线程规则。再次,使用 SwingWorker 并做正确的事情。请阅读Lesson: Concurrency in Swing -
@HovercraftFullOfEels By doesn't work 我的意思是 servers.add() 不会向服务器 ArrayList 添加任何内容,而 servers.size() == 0 在使用 add() 后会给出 false t 工作,但是如果我将 servers.size() 打印到控制台,它会给出 0。
-
如果这是我的代码,我会将这段代码与 GUI 分开并单独调试。分而治之。运行后,我会尝试通过
SwingWorker<List<String>, Void>将其网格化到 GUI 中,并在工作人员的doInBackground()方法中返回列表。 -
@Hovercraft 你不能让它变得不稳定。一方面,您只能使字段易变,而不是局部变量。另一方面,这实际上是最终的,你不能使某些东西成为最终的和易变的。
标签: java multithreading swing arraylist