完全退出Java方法

时间:2014-12-21 17:20:35

标签: java guava time-limiting

我的方法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();

            }

        }

    }

2 个答案:

答案 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的实施中,如果可能的话。