【发布时间】:2020-09-21 15:06:58
【问题描述】:
我正在编写一个应用程序(供个人使用),它允许我通过 USB 将字符串发送到 Arduino。
我写了这个发送数据的方法:
/**
* Sends the data to the Arduino.
* A new Thread is created for sending the data.
* A transmission cool-down is started before send() method can be used again.
* @param data the data to send to the Arduino
*/
public void send(String data) {
if (connected && !sending) {
// Set 'sending' to true so only 1 Thread can be active at a time
sending = true;
// Create a new thread for sending the data
Thread thread = new Thread(() -> {
// Send the data
PrintWriter output = new PrintWriter(chosenPort.getOutputStream());
output.print(data);
System.out.println("Data sended");
output.flush();
// Wait for the transmission cool-down and set 'sending' to false to allow for another Thread to send data
try { Thread.sleep(transmissionCoolDown); } catch (InterruptedException interruptedException) { interruptedException.printStackTrace(); }
sending = false;
System.out.println("cooldown is over");
});
thread.start();
}
}
sending 是一个布尔值,我用它来指示线程是否正在发送数据。 transmissionCooldown 只是在数据可以再次发送之前强制执行一定的等待时间。
这是使用该方法的地方:
@FXML
private void sendClicked() {
// Only do something if a connection is active and an image is selected.
// Should be unnecessary since the send button is only enables when both are true.
if (connected && selectedIV.getImage() != null) {
if (!sending) {
// Save the original text of the send button and disable the disconnect button
String ogText = sendButton.getText();
System.out.println(ogText);
connectButton.setDisable(true);
// If the data has not been saved before, get the data by formatting the image
if (data == null) {
data = imgCon.toStringFormat(true);
}
ardComm.send(data);
// While the ArduinoCommunicator is busy sending, change the text on the send button to indicate the data is being transmitted
sendButton.setText("busy");
while (ardComm.isSending()) {
}
// Restore the text on the send button
sendButton.setText(ogText);
connectButton.setDisable(false);
}
}
}
sendButton 是调用sendClicked() 方法的JavaFX 按钮,ardCom 是包含send() 方法的类的实例。 isSending() 只是返回ardCom 的发送属性,在send() 方法开始时设置为true,在线程完成发送时设置为false。
问题出在这段代码上:
sendButton.setText("busy");
while (ardComm.isSending()) {
}
// Restore the text on the send button
sendButton.setText(ogText);
我正在尝试将sendButton 的文本设置为忙以指示正在发送数据,然后循环直到数据传输完成(发送设置为 false)并以更改文本结束sendButton 回到原文。我知道这可能不是实现这一目标的最佳方法,但我一直在玩,无法弄清楚为什么它没有按预期工作。
问题是由于某种原因,while 循环永远不会结束。
【问题讨论】:
-
将 JavaFx 应用程序视为在单线程上运行的应用程序。当这个线程忙于运行长时间循环
while (ardComm.isSending())时,它不会更新 gui。 gui 变得无响应(冻结)。 -
发送不稳定吗?
标签: java multithreading javafx