尽管条件为假,但循环仍在继续运行

时间:2015-09-01 11:34:34

标签: java

好的,我在修复这个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()我不知道或不知道问题可能在哪里?

1 个答案:

答案 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,如果您愿意,可以使用多个实例。