我在Windows 10上使用JavaSE-1.8。我有以下意外行为。我还使用Paho Mqtt客户端,并且服务器在虚拟机中运行。
设置:
在main函数中,有一个while循环,循环直到变量terminate_by_mqtt
为真。当外部客户端(例如Linux上的mosquitto_pub
)将任何内容写入主题时,将设置此变量:"terminate"
以下代码按预期工作:
Main.java:
public class Main{
static Vehicle vehicle;
private static boolean terminate_by_mqtt = false;
public static void main(String[] args) {
MqttClient client = null;
try {
String clientId = "ECU1";
String broker = "tcp://192.168.56.1:1883";
client = new MqttClient(broker, clientId);
MqttConnectOptions connOpts = new MqttConnectOptions();
connOpts.setCleanSession(true);
client.connect(connOpts);
System.out.println("Connected");
client.subscribe("terminate");
client.setCallback(new TopicCallback());
terminate_by_mqtt = false;
// ***** This while loop is the symptom ****
while (true) {
if(terminate_by_mqtt) break;
// Works with flush or println. Remove this line and loop hangs
System.out.flush();
}
System.out.println("loop termianted");
System.out.println("Disconnected");
System.out.flush();
} catch (MqttException me) {
}
// ... Code below (or no code) does not impact the problem
}
static public synchronized void setTermination(boolean v) {
terminate_by_mqtt = v;
}
}
TopicCallback.java实现MqttCallback
以下函数处理回调。请注意,这在另一个线程上运行。
@Override
public void messageArrived(String arg0, MqttMessage msg) throws Exception {
// TODO Auto-generated method stub
byte[] bytes = msg.getPayload();
String x = new String(bytes, "UTF-8");
System.out.print(x);
System.out.flush();
// Causes while loop to terminate if we write to "terminate" topic
if(arg0.equals("terminate")) {
Main.setTermination(true);
}
}
问题:
如代码中所示,当我将标志设置为true时,有一个while循环不会终止。如果我在while循环中添加System.out.flush()
,那么就没有问题。如果我删除该行,则while循环不会终止。
然后我尝试在Eclipse中调试程序。
"terminate"
主题。if(terminate_by_mqtt) break;
行上我试图在循环中进行一些算术运算,但这并不能像System.out.flush()那样帮助解决问题。
好像代码在“忽略”那行,认为它不会改变(也许是由于一些优化工作?)。我不知道该如何证明/反驳。
问题:
知道发生了什么吗?