私はあなたのクラスAsyncTestを強化しています
public class RetryableAsyncTest implements Callable<RetryableAsyncTest> {
private final String _name;
private /* */ String _value;
private /* */ boolean _timeouted;
private /* */ int _retryCount;
public RetryableAsyncTest(String name) {
_name = name;
}
@Override
public RetryableAsyncTest call() throws Exception {
try {
++_retryCount;
_timeouted = false;
//-------- Begin of functionnal code
if(Math.random() > 0.5) { // Simulation of
throw new TimeoutException(); // timeout condition
}
_value = "computation result";
//-------- End of functionnal code
}
catch(final TimeoutException x) {
_timeouted = true;
}
return this;
}
public String getName() {
return _name;
}
public String getValue() {
return _value;
}
public boolean isTimeouted() {
return _timeouted;
}
public int getRetryCount() {
return _retryCount;
}
}
RetryableAsyncExecutorクラス:
public class RetryableAsyncExecutor {
private final ExecutorService _exec;
private final CompletionService<RetryableAsyncTest> _comp;
public RetryableAsyncExecutor(int nThreads) {
_exec = Executors.newFixedThreadPool(nThreads);
_comp = new ExecutorCompletionService<>(_exec);
}
public void submit(RetryableAsyncTest task) {
_comp.submit(task);
}
public RetryableAsyncTest get() throws Exception {
final Future<RetryableAsyncTest> f = _comp.take();
final RetryableAsyncTest task = f.get();
if(task.isTimeouted()) {
_comp.submit(task);
}
return task;
}
public void shutdown() {
_exec.shutdown();
}
}
テストケース:
public class Main {
public static void main(String[] args) {
final int COUNT = 8;
final RetryableAsyncExecutor re = new RetryableAsyncExecutor(5);
try {
for(int i = 0; i < COUNT; ++i) {
re.submit(new RetryableAsyncTest("Async#"+(i+1)));
}
int count = 0;
while(count < COUNT) {
final RetryableAsyncTest task = re.get();
if(task.isTimeouted()) {
System.err.printf("%s: retrying (%d)\n",
task.getName(), task.getRetryCount());
}
else {
System.err.printf("%s: done with '%s'.\n",
task.getName(), task.getValue());
++count;
}
}
}
catch(final Throwable t) {
t.printStackTrace();
}
re.shutdown();
System.exit(0);
}
}
実行ログ:
Async#4: done with 'computation result'.
Async#1: done with 'computation result'.
Async#6: retrying (1)
Async#3: done with 'computation result'.
Async#8: done with 'computation result'.
Async#7: retrying (1)
Async#2: done with 'computation result'.
Async#5: retrying (1)
Async#6: done with 'computation result'.
Async#7: done with 'computation result'.
Async#5: retrying (2)
Async#5: done with 'computation result'.
あなたが再試行の数を切り上げしたい場合は、このロジックは、ほんの少しの明確化私は確信して、私が何を正確に把握すること答えることを試みる前に_comp.submit(task);
周りのif-then-else条件として、
RetryableAsyncExecutor.get()
方法に行われます続行中です。 TimeoutExceptionは、ネットワークコールの遅延から来ていますが、エグゼキュータがそのビジネスを終了するのを待ってからではありませんか? – Xypeはい、TimeoutExceptionはネットワークコールの遅れから発生しています。 – Harsh
答えを二倍にするのではなく、ここから必要なものを得ることができると思います。https://stackoverflow.com/a/4738630/3630719 – Xype