好的,我在修复这个bug时遇到了一些困难,所以在我再花一天时间搜索之前,我会问你们。
//Core Class
static String serverAnswer = "";
public static void sendMessage(String msg){
serverAnswer = "";
Connection.send(msg);
while(serverAnswer.equals("")); <infinity loop
}
//Connection Thread
public void run() {
while(running){
try {
msg = (String)in.readObject();
Core.serverAnswer = msg;
} catch (StreamCorruptedException e){
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
实际上线程应该等到服务器响应然后设置答案
所以循环应该停止,但我不会停止...
我检查过以下内容:
Core.serverAnswer
明确地从服务器获取一个字符串。那么有什么关于while()
我不知道或不知道问题可能在哪里?
答案 0 :(得分:8)
除非您使用volatile
,否则JVM可以自由内联该值。特别是它可以完全自由地优化读取,而不再检查它。
您需要制作字段volatile
。
一种破坏此优化以使线程安全操作的方法。
while(serverAnswer.equals(""))
Thread.yield();
然而,更好的解决方案是将对象读入BlockingQueue
public class TextSocket implements Closeable {
final Socket socket;
private final BufferedReader reader;
private final PrintWriter writer;
public TextSocket(String hostname, int port) throws IOException {
this(new Socket(hostname, port));
}
public TextSocket(Socket socket) throws IOException {
this.socket = socket;
reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8));
}
public String sendAndRead(String msg) throws IOException {
writer.println(msg);
if (writer.checkError())
throw new IOException("Unable to write");
writer.flush();
return reader.readLine();
}
@Override
public void close() throws IOException {
socket.close();
}
}
我还建议你避免使用像这样的静态字段。您可以使用实例字段实现Connection,如果您愿意,可以使用多个实例。