我想实施一个名为:
的电话public Response getContent() throws MyException
此方法在内部调用Web服务,但我只希望同时向Web服务发出一个请求。也就是说:当第一个请求到来时,它将转到Web服务。如果同时另一个请求到达,则等待第一个请求的结果。在第一个请求返回(或抛出异常)之后,所有挂起的请求也会返回(或抛出异常)。从这一点开始,如果另一个请求到来,它将再次转到具有相同标准的Web服务(同时只有一个Web服务调用)
在Java / Android中实现此功能的最佳方法是什么?
由于
答案 0 :(得分:3)
这是一个CompletableFuture
的解决方案,它始终阻止等待新结果。如果您调用get()
并且存在现有结果,则会触发新的提取和阻止。如果提取已在进行中,它将加入等待该结果的其他线程。
import java.util.concurrent.CompletableFuture
import java.util.concurrent.atomic.AtomicReference
class OneAtATime<out T> {
private val pending = AtomicReference(CompletableFuture<T>())
init {
startFetching(pending.get())
}
fun get(): T {
val current = pending.get()
if (!current.isDone) {
return current.get()
}
val next = CompletableFuture<T>()
return if (pending.compareAndSet(current, next)) {
startFetching(next)
next.get()
} else {
pending.get().get()
}
}
private fun startFetching(future: CompletableFuture<T>) {
TODO("Implementation must call future.complete(newContent)")
}
}
答案 1 :(得分:1)
我建议开始学习阻塞队列的工作原理:
BlockingQueue
之后,您可以开始调查解决方案,以便一次拨打一个电话。一种解决方案是使用信号量:
Blocking queue with a semaphore
(来自上面的链接)适用于您的案例的摘录:
编辑
public class CustomBlockingQueue {
private List<Object> queue = new LinkedList<Object>();
private int limit;
private Semaphore mutex; // for the critical section
public CustomBlockingQueue() {
this.mutex = new Semaphore(1);
}
//enqueue can be process task, etc.
private void enqueue(Object o) throws InterruptedException {
mutex.acquire(); // critical section starts
queue.add(o); //or custom operation
mutex.release(); // critical section ends
}
//as pointed out in the comments this is more queue related
private Object dequeue() throws InterruptedException {
mutex.acquire(); // critical section starts
Object o = queue.remove(0);//or custom operation
mutex.release(); // critical section ends
return o;
}
}