Другой подход (который, я думаю, может быть даже лучше) состоит в добавлении всех потоков, которые запрашивают результат, в синхронизированную коллекцию. Затем, когда результат прибудет - отправьте ответы обратно в потоки. Вы можете использовать потребительский интерфейс java 8, чтобы сделать его более привлекательным. Это не будет тратить процессорное время (как с thread.sleep или даже с countDownLatch и другими современными классами параллельных Java-вычислений). Требуется, чтобы эти потоки имели метод обратного вызова для принятия результата, но это могло бы даже облегчить чтение вашего кода:
class MyService {
private static volatile boolean isProcessing;
private synchronized static boolean isProcessing() {
return isProcessing;
}
private static Set<Consumer<String>> callers=Collections.synchronizedSet(new HashSet<>());
void serviceApiMmethod(Consumer<String> callBack) {
callers.add(callBack);
callSlowOperation();
}
private synchronized static void callSlowOperation() {
if(isProcessing())
return;
isProcessing=true;
try { Thread.sleep(1000); }catch (Exception e) {}//Simulate slow operation
final String result="slow result";
callers.forEach(consumer-> consumer.accept(result));
callers.clear();
isProcessing=false;
}
}
И вызывающие темы:
class ConsumerThread implements Runnable{
final int threadNumber;
public ConsumerThread(int num) {
this.threadNumber=num;
}
public void processResponse(String response) {
System.out.println("Thread ["+threadNumber+"] got response:"+response+" at:"+System.currentTimeMillis());
}
@Override
public void run() {
new MyService().serviceApiMmethod(this::processResponse);
}
}
Таким образом, получающийся объект будет собирать мусор, потому что все потребители сразу его получат и выпустят.
И для проверки результатов:
public class Test{
public static void main(String[] args) {
System.out.println(System.currentTimeMillis());
for(int i=0;i<5;i++) {
new Thread(new ConsumerThread(i)).start();
}
}
}
И результат:
1542201686784
Thread [1] got response:slow result at:1542201687827
Thread [2] got response:slow result at:1542201687827
Thread [3] got response:slow result at:1542201687827
Thread [0] got response:slow result at:1542201687827
Thread [4] got response:slow result at:1542201687827
Все темы получили результат через 1 секунду. Вид реактивного программирования;) Это действительно меняет способ на более асинхронный, но если вызывающий поток хочет заблокировать выполнение при получении результата, он может его достичь. Сервис в основном говорит о том, что сделано. Это все равно что сказать: «моя операция медленная, поэтому вместо того, чтобы выполнять вызов для каждого из вас, я отправлю вам результат, как только буду готов - дайте мне потребительский метод»