2012-11-09 8 views
2

안녕하세요, JBoss 6.0 Final의 비동기 메서드 호출에 문제가 있습니다.Future.get (long timeout, TimeUnit unit)이 JBoss 6에서 반환되지 않습니다.

클래스는 다음과 같이 :

하나는 개체의 수를 포함 스토리지 그냥 일종이다.

@Singleton 
public class Storage { 

    private Map<Integer, Object> storage = new HashMap<Integer, Object>(); 

    @Asynchronous 
    public Future<Object> getAsync(int id) { 
     Object obj = null; 
     while (null == obj) { 
      obj = storage .remove(id); 
     } 
     return new AsyncResult<Object>(obj); 
    } 

    public void add(int id, Object obj) { 
     storage.put(id, obj( 
    } 
} 

그런 다음 어떤 것을 처리하고 주어진 ID로 저장소에서 개체를 찾으려고하는 클래스가 있습니다. 그것은 지정된 시간 동안 기다려야 만이 id에 대한 객체를 저장소에서 찾을 수 있습니다. 아무것도가없는 경우 검색을 중단하고 계속 :

@Singleton 
public class Executor { 

    @Inject 
    private Storage storage; 

    public void execute(int id) { 

     Future<Object> fut = storage.getAsync(id); 
     Object obj; 
     try { 
      obj = t.get(30L, TimeUnit.SECONDS); 
        // go on processing of obj is found 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } catch (ExecutionException e) { 
      e.printStackTrace(); 
     } catch (TimeoutException e) { 
      //no object can be found. 
      // but we never reach this place 
     } 
    } 
} 

이 저장 내의 지정된 ID에 대한 객체가없는 경우가 발생할 수 있으므로 getAsync에서 루프() 메소드는 '무한'입니다. 그래서 30 초 후에 TimeoutException을 throw해야합니다. 재미있는 점은 TimeoutException은 결코 throw되지 않는다는 것입니다.

비동기 메서드에서 '무한'루프를 만들지 않는 것과 같은 요점이 누락 되었습니까?

UPDATE :

내가 독립 실행 형 응용 프로그램에 비슷한 일을 수행 할 때 제대로 작동하고 :

public class Test { 
    public static void main(String[] args) { 
     ExecutorService executor = Executors.newFixedThreadPool(10); 
     Callable<Object> task = new Callable<Object>() { 
      public Object call() { 
       int i = 0; 
       while(i == 0) { 
        i = 0; 
       } 
       return null; 
      } 
     }; 
     Future<Object> future = executor.submit(task); 
     try { 
      Object result = future.get(5, TimeUnit.SECONDS); 
     } catch (TimeoutException ex) { 
      ex.printStackTrace(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } catch (ExecutionException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

을 그래서 기본적으로 비동기 방식의 무한 루프를하고 있기 때문에 독립에 괜찮이다 TimeoutException catch 블록이 호출되었습니다!

UPDATE 나는이 비슷한을 가진 getAsync() 방법을 대체 II

get() 반환 성공적으로 TimeoutException를 throw하지 않고. 그러나 그것은 내가 기대할 것입니다!

@Asynchronous 
public Future<Telegram> getTelegramAsync(int telegramId) { 
    Telegram tlgrm = null; 
    try { 
     Thread.sleep(10000); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    return new AsyncResult<Telegram>(tlgrm); 
} 

아무 도움이됩니다.

관련

답변

0

시간 초과 예외가 없다는 t.get이 실행되지 않습니다 때문이다. while 루프에 갇혀 있습니다. getAsync. 미래를 한 번에 그리고 미래 구현으로 되돌려 야 할 때, 예를 들어 카운트 다운 래치를 사용하여 결과가 나오거나 타임 아웃이 될 때까지 기다려야합니다 ...

+0

감사합니다. Fildor. 그러나 그것은 사실이 아닙니다. [@Asynchronous] (http://docs.oracle.com/javaee/6/api/javax/ejb/Asynchronous.html) 메소드에 주석을 추가하면 컨테이너가 나중에이 메소드를 호출 할 때 Future 객체를 반환합니다. 'get()'메쏘드로 complettion을 검사했습니다. – Sancho

+0

편집 후에 보았던 것에서부터, 나는 여전히 그 무한 루프를 할 것입니다. 그걸 밟았 니? 아니면 그것을 프로파일 링? 어떤 로그 아웃으로도 충분합니다. 첫 번째 편집의 무한 루프는 다른 루프와 동일하지 않습니다. ExecutorService가이를 처리하기 때문입니다. – Fildor

+0

'Future' 스타일로 실행할 수 없으므로 제안한'CountdownLatch' 아이디어로 해결 방법을 만들었습니다. 어쨌든 고마워. – Sancho