2014-12-21 4 views
0

내 메소드 checkConnection()setPort()을 으로 호출합니다.이 메소드는 메소드가 완료되지 않은 경우 3 초 이내에 호출 메소드를 종료합니다. 위대한 작품과 시간 제한을 초과했을 때 com.google.common.util.concurrent.UncheckedTimeoutException의 예외가 있습니다. 그러나이 예외가 throw 된 후에도 setPort이 여전히 실행되고 한 번 완료되면 내 try 문 내에서 포트가 열리면 코드가 실행되고 Thread.sleep(100)이되면 InterruptedException이 발생하고 메서드가 종료됩니다. 그러나 이로 인해 문제가되는 포트가 생겨납니다. 제한 시간이 초과되어 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

당신이이 당신이 진정한 통과 시도하고 .Also를 작동하는지 나는 강한 느낌 setPort가 가지고있는 볼 당신은 false.Can로 amInterruptible을 전달하는

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. 

의 서명입니다 작동한다면, 시도 할 수 사용자 Scadge 방금이 빠른 해결책은 당신

+0

set port 메소드를 코드에 추가했습니다. 나는 그것을 시도했지만 작동하지 않는 것 같습니다. 시간 제한이 끝난 후에도 Thead.sleep (100)에 도달 할 때까지 모든 코드가 정상적으로 실행되지만 중단되는 코드는 즉시 중지됩니다. –

+0

setPort가 끝날 때이 체크를 추가 할 수 있습니다. if (Thread.interrupted()) {serialPort.close(); new InterruptedException()}을 던지고 setPort를 호출하는 메소드의 catch 블록에 포트가 있으면이를 닫습니다. setPort를 인터럽트 가능하게 만들어서 클라이언트가 setPort를 호출하여 어떤 이점을 얻을 수 있는지 클라이언트에게 알려주는 것이 이상적입니다. –

+0

컴파일 에러가 발생하면 setPort 메소드를 선언하여 InterruptedException을 발생시켜야합니다. setPort는 공개적이고 정적 인 메소드입니다. 많은 클라이언트가이 메소드를 호출 할 수 있기 때문에 이것을 제안했습니다.그것이 개인적인 방법 이었다면 이것은 필요하지 않다. –

1

위해 일할 수있는 희망의 implementations.Anyways를 제공 할 필요가 댓글을 달았습니다 것처럼 그 .FOR 인터럽트가이입니다 SimpleTimeLimiter의 문서화 된 행동 :

ExecutorService를 사용하여 백그라운드에서 메서드 호출을 실행하는 TimeLimiter입니다. 주어진 메소드 호출에 대한 시간 제한이 만기되면 호출을 실행하는 스레드가 인터럽트됩니다.

기본적으로 스레드를 "인터럽트"한다는 것은 인터럽트 플래그가 설정되었음을 의미합니다 (Thread.interrupt() 설명서에 언급 된 조건 중 하나가 아니면). 따라서 플래그는 단지 내부 스레드 (예외 스레드가 을 실행하는 스레드) 내에서 throw되지 않고 설정됩니다.

해당 스레드가 sleep()을 호출하는 지점에 도달하면 인터럽트 플래그가 읽혀 스레드를 즉시 중단합니다 .

은 당신이 할 수있는 것은 Thread.interrupted() 또는 Thread.isInterrupted() 방법을 확인하고, 중단이 있다면, 포트를 (등, 닫습니다) 정리. 당신은 InterruptedException을 잡는 try 내부 전체를 놓고, 수 수행 한 각각의 오랜 작업 후에 InterruptedExceptionThread.interrupted()으로 설정하면 true - setPort, openPort

가능한 경우 가능한 한 빨리이 작업을 수행하는 것이 가장 바람직합니다. 구현 가능한 경우 setPort을 구현하는 것이 가장 좋습니다.

+0

if (Thread.interrupted())를 추가했습니다. {serialPort.closePort(); 새로운 InterruptedException()를 던지십시오. } 코드를 중지합니다 setPort 메서드 후. 그러나 setPort 메소드 내에서 실행되는 코드는 계속 실행되며 일단 포트가 설정되면 재설정 할 수 없거나 포트 바쁜 예외가 발생합니다. setPort 메서드 내에서 Thread.interrupted()를 도달 할 수없는 코드로 사용할 수 없습니다. –

+0

'InterruptedException'을 throw하는 것으로 선언하면 포트 조작의 각 단계를 확인하고 실제'InterruptedException'을 던져야합니다. 그렇지 않으면'catch' 코드에 도달 할 수 없습니다. 당신이 그것을 다시 설정할 수 없다는 사실에 관해서는, 당신은 아마도 당신이 얻을 수있는 전체 스택 추적을 제공해야한다. – RealSkeptic