我的方法checkConnection()
在setPort()
内调用TimeLimiter
,如果方法尚未完成,则会在3秒内退出调用方法。这很好用,超过时间限制时com.google.common.util.concurrent.UncheckedTimeoutException
有例外。但是,即使在抛出此异常后,setPort
仍然运行并且一旦完成,我的try语句中打开端口的代码就会运行,但是一旦它到达Thread.sleep(100)
,就会抛出InterruptedException,然后该方法退出。然而,这给我留下了一个导致问题的开放端口。一旦超过时间限制,call()
方法中的所有代码都会停止吗?
public static String checkConnection(final String comPort) {
final String port = comPort;
String result = null;
TimeLimiter limiter = new SimpleTimeLimiter();
try {
result = limiter.callWithTimeout(new Callable<String>() {
public String call() {
// Try to set serial port
String setPort = setPort(comPort);
// Check for any exceptions
if(setPort.contains("jssc.SerialPortException")) {
if(setPort.contains("Port busy")) {
return "Error: The port appears to be busy";
} else {
return "Error: Can't connect to port";
}
}
try {
// Port can't be accessed twice at the same time
synchronized(portLock) {
// Open port if not already opened
if(!serialPort.isOpened())
serialPort.openPort();
// Sleep while response is being sent
Thread.sleep(300);
// Check for response
buffer = serialPort.readBytes(6);//Read 6 bytes from serial port
serialPort.closePort();
}
// Parse response as string
response = new String(buffer);
} catch (SerialPortException | InterruptedException e) {
System.out.println("Serial:: ping() :: Exception while pinging Noteu : " + e);
return "Error";
}
return response;
}
}, 3, TimeUnit.SECONDS, false);
} catch (Exception e) {
System.out.println("Serial:: checkConnection() :: Exception while calling ping : " + e);
}
}
public static String setPort(String port) {
synchronized(portLock) {
try {
System.out.println("Serial:: setPort() :: Opening Port...");
serialPort = new SerialPort(port);
if(!serialPort.isOpened())
serialPort.openPort();
System.out.println("Serial:: setPort() :: Setting Params...");
serialPort.setParams(SerialPort.BAUDRATE_9600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
System.out.println("Setting Port3");
serialPort.closePort();
System.out.println("Serial:: setPort() :: Port Set...");
return "Success";
} catch (SerialPortException e) {
System.out.println("Serial:: setPort() :: Exception at set Port : " + e.toString());
return e.toString();
}
}
}
答案 0 :(得分:1)
你可以尝试这是否有效这是
的签名callWithTimeout(Callable<T> callable,
long timeoutDuration,
TimeUnit timeoutUnit,
boolean amInterruptible)
........
amInterruptible - whether to respond to thread interruption by aborting the operation and throwing InterruptedException; if false, the operation is allowed to complete or time out, and the current thread's interrupt status is re-asserted.
你传递amInterruptible是假的。你可以尝试传递true并查看它是否有效。我也有强烈的感觉setPort必须是可中断的。因为用户Scadge评论你需要提供它的实现。不管怎样只是希望这个快速解决方案可能适合您
答案 1 :(得分:1)
这是SimpleTimeLimiter
的记录行为:
使用ExecutorService在后台运行方法调用的TimeLimiter。如果给定方法调用的时间限制到期,则运行该调用的线程将被中断。
基本上,&#34;打断&#34;一个线程意味着它的中断标志被置位(除非Thread.interrupt()
文档中提到的一个条件成立)。所以只设置了标志,内部线程(执行setPort
的线程)没有任何异常抛出。
一旦该线程到达它调用sleep()
的点,则读取中断标志并立即中止该线程。
您可以做的是检查Thread.interrupted()
或Thread.isInterrupted()
方法,如果有中断,请清理端口(关闭它等)。您可以将整个内容放入try
中捕获InterruptedException
,并在每次执行长操作后InterruptedException
为真时抛出Thread.interrupted()
,setPort
,{ {1}}等等。
事实上,最好尽早做到这一点,所以也许在openPort
的实施中,如果可能的话。