2014-12-21 3 views
0

Мой метод checkConnection() вызывает setPort() в пределах TimeLimiter, который выходит из метода вызова в течение 3 секунд, если метод еще не закончен. Это отлично работает и есть исключение из com.google.common.util.concurrent.UncheckedTimeoutException, когда предел превышен. Однако даже после того, как это исключение заброшено, setPort все еще запускается и после его завершения код в моей инструкции try, открывающей порт, работает, но как только он добирается до Thread.sleep(100), прерванное Exception вызывается, тогда метод выходит. Однако это оставляет меня открытым портом, который вызывает проблемы. Есть ли способ, когда превышен лимит времени, что весь код в методе call() остановится?Полный метод Java

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

Я думаю, что это поможет, если вы предоставите хотя бы часть реализации setPort(). – Scadge

+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 в false.Can попытке прохождения верно и посмотреть, работает ли он .Также у меня есть сильное чувство setPort имеет чтобы быть прерывистым .Для что, как Scadge Пользователь прокомментировал вы должны предоставить свои implementations.Anyways просто надеясь, что это быстрое решение может работать для вас

+0

Я добавил метод set port к моему коду. Я пробовал, что, похоже, это не работает. Даже после того, как ограничение по времени заканчивается, весь код работает нормально, пока он не достигнет Thead.sleep (100), где он прерывается, однако я хочу, чтобы код немедленно остановился. –

+0

В конце setPort вы можете добавить эту проверку, если (Thread.interrupted()) {serialPort.close(); throw new InterruptedException()} и в блоке catch метода, который вызывает setPort, закрывает порт, если он задан. Это сделает прерывание setPort идеальным, желательно, как вы хотите, чтобы любой из ваших клиентов, кто звонил setPort, извлекал из него выгоду –

+0

Это вызовет ошибку компиляции, которую вам придется объявить методом setPort, чтобы вызывать InterruptedException. Поскольку setPort является общедоступным и статическим методом, я считаю, что многие клиенты могут вызвать этот метод, поэтому я предложил это.Если это был частный метод, тогда это не было необходимо –

1

Это документально поведение SimpleTimeLimiter:

TimeLimiter, который запускает метод вызовов в фоновом режиме с помощью ExecutorService. Если истечение срока для данного вызова метода, поток, выполняющий вызов, будет прерван.

В принципе, «прерывание» нити означает, что установлен флаг прерывания (если не указано одно из условий, упомянутых в документации Thread.interrupt()). Таким образом, флаг только что установлен, без каких-либо исключений, созданных во внутреннем потоке (поток, который выполняет setPort.

После того, как этот поток попадает в точку, где он вызывает sleep(), тогда флаг прерывания считывается и немедленно прерывает поток .

что вы можете сделать, это проверить Thread.interrupted() или Thread.isInterrupted() методов, и если был перерыв, очистить порт (закрыть его и т.д.). вы можете поместить все эти внутри try, что попадается InterruptedException и бросить InterruptedException, если Thread.interrupted() истинно после каждой длительной операции, которую вы выполняете - setPort, openPort и т. Д.

На самом деле, было бы лучше сделать это как можно раньше, поэтому, возможно, внутри реализации setPort, если это возможно.

+0

Я добавил, если (Thread.interrupted()) {serialPort.closePort(); throw new InterruptedException(); } после метода setPort, который останавливает код. Однако код, запущенный в методе setPort, все еще выполняется, и как только порт установлен, я не могу его сбросить или я получаю исключение из порта. Я не могу использовать Thread.interrupted() в методе setPort как его недостижимый код. –

+0

Если вы объявите его как «throws InterruptedException», вам также необходимо проверить после каждого шага манипуляции с портом и выбросить фактическое 'InterruptedException', иначе код' catch' недостижим. Что касается того, что вы не можете сбросить его, вы должны, вероятно, получить полную трассировку стека, которую вы получите. – RealSkeptic

Смежные вопросы