Все, у меня есть вызов api, который вызывается многими потоками. Единственная проблема заключается в том, что ставка задержки. потоки должны быть не менее 1 секунды. Я понял - без синхронизированного блока - если один поток вызывает api в момент времени t1, тогда все остальные потоки ожидают 1 секунду, а затем все остальные потоки вызовут api при t1 + 1 секунду. Этого я не хочу, поэтому я помещаю весь блок ожидания в синхронизированный блок, если один поток ожидает всех остальных потоков.Создание задержки между потоками
Это работает; однако, я думаю, что это не самый эффективный способ сделать это.
Любые рекомендации приветствуются.
private static volatile AtomicLong lastAPICall = new AtomicLong();
private void callAPI() {
// 1 sec plus a little extra
final long oneMS = 1 * 1000 + 100;
long lastCall = 0;
long timeDiff = 0;
synchronized (lastAPICall) {
timeDiff = System.currentTimeMillis() - lastAPICall.get();
lastCall = lastAPICall.getAndSet(System.currentTimeMillis());
}
}
if (System.currentTimeMillis() - lastCall < oneMS) {
synchronized (lastAPICall) {
try {
long sleep = oneMS - timeDiff;
Thread.sleep(oneMS - timeDiff);
} catch (InterruptedException ignore) {}
finally {
lastAPICall.set(System.currentTimeMillis());
log.info("Thread: " + Thread.currentThread().getId() + " calling the api at this time: " + System.currentTimeMillis());
}
}
}
try {
// API CALL
}
catch (IOException t){
throw t;
} finally {
synchronized (lastAPICall) {
lastAPICall.set(System.currentTimeMillis());
}
}
// Log files for running the code with 4 threads
Thread: 35 calling the api at this time: 1456182353694
Thread: 34 calling the api at this time: 1456182354795
Thread: 37 calling the api at this time: 1456182355905
Thread: 36 calling the api at this time: 1456182357003
Вы хотите, чтобы каждый поток должен был ждать одну секунду после того, как предыдущий поток начал свой вызов, или после того, как предыдущий поток завершил свой вызов? –
Я хочу, чтобы каждый поток подождал одну секунду после того, как предыдущий поток начал свой вызов. – blueSky
Не имеет значения, завершен ли первый вызов или нет. – blueSky