我有一个客户端服务器应用程序,我使用rxjava来处理来自客户端的服务器请求。客户端应该一次只做一个请求,所以我打算使用类似于trampoline调度程序的线程队列调度程序。
现在我尝试实现一种机制来监视服务器上的更改。因此,我发送一个长期生存请求,阻止服务器进行一些更改并发回结果(长拉)。
此长拉取请求应仅在作业队列空闲时运行。我正在寻找一种在计划常规请求时自动停止监视请求的方法,并在队列变空时再次启动它。我想过修改trampoline调度程序以获得这种行为,但我觉得这是一个常见的问题,可能有一个更简单的解决方案?
答案 0 :(得分:1)
您可以通过安排长轮询任务保留返回的订阅,如果队列变为非空则取消订阅,并在队列变空时重新安排。
编辑:以下是基本ExecutorScheduler的示例:
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
public class IdleScheduling {
static final class TaskQueue {
final ExecutorService executor;
final AtomicReference<Future<?>> idleFuture;
final Runnable idleRunnable;
final AtomicInteger wip;
public TaskQueue(Runnable idleRunnable) {
this.executor = Executors.newFixedThreadPool(1);
this.idleRunnable = idleRunnable;
this.idleFuture = new AtomicReference<>();
this.wip = new AtomicInteger();
this.idleFuture.set(executor.submit(idleRunnable));
}
public void shutdownNow() {
executor.shutdownNow();
}
public Future<?> enqueue(Runnable task) {
if (wip.getAndIncrement() == 0) {
idleFuture.get().cancel(true);
}
return executor.submit(() -> {
task.run();
if (wip.decrementAndGet() == 0) {
startIdle();
}
});
}
void startIdle() {
idleFuture.set(executor.submit(idleRunnable));
}
}
public static void main(String[] args) throws Exception {
TaskQueue tq = new TaskQueue(() -> {
while (!Thread.currentThread().isInterrupted()) {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
System.out.println("Idle interrupted...");
return;
}
System.out.println("Idle...");
}
});
try {
Thread.sleep(1500);
tq.enqueue(() -> System.out.println("Work 1"));
Thread.sleep(500);
tq.enqueue(() -> {
System.out.println("Work 2");
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
}
});
tq.enqueue(() -> System.out.println("Work 3"));
Thread.sleep(1500);
} finally {
tq.shutdownNow();
}
}
}