안녕하세요, 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);
}
아무 도움이됩니다.
관련
감사합니다. Fildor. 그러나 그것은 사실이 아닙니다. [@Asynchronous] (http://docs.oracle.com/javaee/6/api/javax/ejb/Asynchronous.html) 메소드에 주석을 추가하면 컨테이너가 나중에이 메소드를 호출 할 때 Future 객체를 반환합니다. 'get()'메쏘드로 complettion을 검사했습니다. – Sancho
편집 후에 보았던 것에서부터, 나는 여전히 그 무한 루프를 할 것입니다. 그걸 밟았 니? 아니면 그것을 프로파일 링? 어떤 로그 아웃으로도 충분합니다. 첫 번째 편집의 무한 루프는 다른 루프와 동일하지 않습니다. ExecutorService가이를 처리하기 때문입니다. – Fildor
'Future' 스타일로 실행할 수 없으므로 제안한'CountdownLatch' 아이디어로 해결 방법을 만들었습니다. 어쨌든 고마워. – Sancho