0

如果方法未完成,我的方法checkConnection()调用在 3 秒setPort()内退出调用方法。TimeLimiter这很好用,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();

            }

        }

    }
4

2 回答 2

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 作为 false 传递。您可以尝试传递 true 并查看它是否有效。此外,我强烈认为 setPort 必须是可中断的。为此,正如 User Scadge 评论的那样,您需要提供其实现。无论如何,希望这个快速的解决方案可能为你工作

于 2014-12-21T17:35:00.547 回答
1

这是记录在案的行为SimpleTimeLimiter

使用 ExecutorService 在后台运行方法调用的 TimeLimiter。如果给定方法调用的时间限制到期,则运行该调用的线程将被中断。

基本上,“中断”线程意味着设置了它的中断标志(除非Thread.interrupt()文档中提到的条件之一成立)。所以标志只是设置,内部线程(执行setPort.

一旦该线程到达它调用的点,就会sleep()读取中断标志并立即中止线程。

你可以做的是检查Thread.interrupted()orThread.isInterrupted()方法,如果有中断,清理端口(关闭它等)。您可以将整个内容放入trythat catchs中,并在您执行的每个长时间操作后InterruptedException抛出InterruptedExceptionif为真 - ,等。Thread.interrupted()setPortopenPort

事实上,最好尽早这样做,所以setPort如果可能的话,也许在 的实现中。

于 2014-12-21T18:05:31.747 回答