完全退出Java方法
我的方法完全退出Java方法,java,guava,time-limiting,Java,Guava,Time Limiting,我的方法checkConnection()在TimeLimiter内调用setPort(),如果方法未完成,该方法将在3秒内退出调用方法。这非常有效,当超过时间限制时,com.google.common.util.concurrent.UncheckedTimeoutException有一个例外。但是,即使在抛出此异常之后,setPort仍然会运行,并且一旦完成,打开端口的try语句中的代码就会运行,但是一旦到达Thread.sleep(100)就会抛出中断异常,然后该方法退出。然而,这给我留下
checkConnection()
在TimeLimiter
内调用setPort()
,如果方法未完成,该方法将在3秒内退出调用方法。这非常有效,当超过时间限制时,com.google.common.util.concurrent.UncheckedTimeoutException
有一个例外。但是,即使在抛出此异常之后,setPort
仍然会运行,并且一旦完成,打开端口的try语句中的代码就会运行,但是一旦到达Thread.sleep(100)
就会抛出中断异常,然后该方法退出。然而,这给我留下了一个导致问题的开放端口。是否有一种方法,一旦超过时间限制,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();
}
}
}
公共静态字符串检查连接(最终字符串组合){
最终字符串端口=comPort;
字符串结果=null;
TimeLimiter limiter=新的SimpleTimeLimiter();
试一试{
结果=limiter.callWithTimeout(新的可调用(){
公共字符串调用(){
//尝试设置串行端口
字符串setPort=setPort(comPort);
//检查是否有例外情况
if(setPort.contains(“jssc.SerialPortException”)){
if(setPort.contains(“端口忙”)){
return“错误:端口似乎正忙”;
}否则{
返回“错误:无法连接到端口”;
}
}
试一试{
//无法同时访问两次端口
已同步(端口锁){
//如果尚未打开,请打开端口
如果(!serialPort.isOpened())
serialPort.openPort();
//发送响应时睡眠
睡眠(300);
//检查是否有响应
buffer=serialPort.readBytes(6);//从串行端口读取6个字节
serialPort.closePort();
}
//将响应解析为字符串
响应=新字符串(缓冲区);
}catch(SerialPortException | InterruptedException e){
System.out.println(“串行::ping()::ping时异常注意事项:”+e);
返回“错误”;
}
返回响应;
}
},3,TimeUnit.s,false);
}捕获(例外e){
System.out.println(“串行::检查连接()::调用ping时异常:”+e);
}
}
公共静态字符串设置端口(字符串端口){
已同步(端口锁){
试一试{
System.out.println(“串行::设置端口()::打开端口…”);
serialPort=新的serialPort(端口);
如果(!serialPort.isOpened())
serialPort.openPort();
System.out.println(“串行::设置端口()::设置参数…”);
serialPort.setParams(serialPort.BAUDRATE_9600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
串行端口。奇偶校验(无);
System.out.println(“设置端口3”);
serialPort.closePort();
System.out.println(“串行::设置端口()::端口集…”);
返回“成功”;
}捕获(SerialPortException e){
System.out.println(“串行::设置端口()::设置端口异常:”+e.toString());
返回e.toString();
}
}
}
你能试一下吗这是的签名
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.
callWithTimeout(可调用、可调用、,
超时时间长,
时间单位时间单位,
布尔值(可中断)
........
AMINTERRUPTABLE—是否通过中止操作和抛出InterruptedException来响应线程中断;如果为false,则允许操作完成或超时,并重新断言当前线程的中断状态。
您正在将AMINTERRUPTABLE传递为false。您能否尝试传递true,看看它是否有效。此外,我强烈感觉setPort必须是可中断的。对于这一点,正如User Scadge所评论的,您需要提供它的实现。无论如何,只希望这个快速解决方案对您有效。这是
SimpleTimeLimiter
:
使用ExecutorService在后台运行方法调用的TimeLimiter。如果给定方法调用的时间限制过期,则运行调用的线程将被中断
基本上,“中断”线程意味着设置了它的中断标志(除非thread.interrupt()
文档中提到的某个条件成立)。因此,只需设置该标志,而不会在内部线程(执行setPort
的线程)中引发任何异常
一旦该线程到达调用sleep()
的点,就会读取中断标志并立即中止该线程
您可以做的是检查Thread.interrupted()
或Thread.isInterrupted()
方法,如果有中断,请清理端口(关闭端口等)。您可以将整个内容放入捕获中断异常的try
中,如果Thread.interrupted()
在每次执行长时间操作后都为true-setPort
,openPort
等,则抛出InterruptedException
事实上,最好尽早这样做,因此可能在setPort的实现中