![](/img/trans.png)
[英]Java: How to break loop when using Executorservice and future for timer?
[英]Using a Timer to break a loop
我正在嘗試為呼叫/響應ping建立超時。 這是為了確定在自動連接順序中使用哪個CommPort。 當我發送CALL_SIGNAL
byte []時,我希望得到“ FU”的回復。 這就是我將確定哪個設備的方式。 SSCCE在下面(對不起,長度,但這是縮短的版本)
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.Timer;
import java.util.TimerTask;
import javax.comm.CommPortIdentifier;
import javax.comm.CommPort;
import javax.comm.PortInUseException;
import javax.comm.SerialPort;
public class PingTest {
public static final long PING_TIMEOUT = 1000; // in millis
public static final byte[] CALL_SIGNAL = {70, 68, 73, 68};
public boolean ping(CommPortIdentifier cpi) {
System.out.println("Pinging " + cpi.getName());
CommPort port = null;
InputStream input = null;
OutputStream output = null;
//Initialization test
try {
port = cpi.open("pingTest", 50);
input = port.getInputStream();
output = port.getOutputStream();
} catch (PortInUseException ex) {
if (cpi.getCurrentOwner().startsWith("pingTest")) {
System.out.println("Port already owned by this application.");
return true;
}
return false;
} catch (Exception ex) {
try {
port.close();
} catch (NullPointerException e) {
}
System.out.println("Failed initialization test.");
System.err.println(ex);
return false;
}
System.out.println("Passed initialization test.");
//Call and response test
final Stop stop = new Stop();
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("Stop timer triggered.");
stop.shouldStop = true;
}
}, PING_TIMEOUT);
try {
System.out.println("Writing...");
output.write(CALL_SIGNAL);
System.out.println("Reading...");
boolean waitForF = true;
while (!stop.shouldStop && !stop.didPass) {
if (waitForF) {
if ((byte) 'F' == input.read()) {
waitForF = false;
}
} else {
System.out.println('F');
if ((byte) 'U' == input.read()) {
System.out.println('U');
stop.didPass = true;
} else {
System.out.println();
waitForF = true;
}
}
}
} catch (IOException ex) {
System.out.println("Failed I/O test.");
return false;
} finally {
port.close();
}
if (stop.didPass) {
System.out.println("Successful ping.");
return true;
}
System.out.println("Failed call and response test.");
return false;
}
public static void main(String[] args) {
PingTest pinger = new PingTest();
Enumeration<CommPortIdentifier> ports = CommPortIdentifier.getPortIdentifiers();
boolean trigger = true;
String name = null;
while (trigger && ports.hasMoreElements) {
CommPortIdentifier cpi = ports.nextElement();
name = cpi.getName();
trigger = !ping(cpi);
}
if (trigger) {
System.out.println("Found it. It is " + name);
} else {
System.out.println("Not Found");
}
}
}
class Stop {
boolean shouldStop = false;
boolean didPass = false;
}
我的輸出是:
Pinging COM1
Passed initialization test.
Writing...
Reading...
Stop timer triggered.
然后應用程序凍結。 嘗試使用Timer
停止while循環是否存在問題?
您的閱讀受阻。 您需要使用超時
您正在從不同線程並發地訪問共享狀態( shouldStop
和didPass
變量),而沒有任何同步。 如果要確保閱讀其他線程寫的內容,則應同步每個訪問。
因此,或者添加方法來獲取和設置這些變量,並使這些方法同步,或者,如果每個變量代表彼此不同的信息並且可以獨立地進行寫入和讀取,則使這些變量易變。
第三種方法(僅在與易失性解決方案相同的條件下有效)是使用AtomicBoolean變量而不是布爾變量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.