rxjava:具有默认空闲作业的队列调度程序

时间:2014-07-19 23:54:26

标签: scheduler rx-java job-queue

我有一个客户端服务器应用程序,我使用rxjava来处理来自客户端的服务器请求。客户端应该一次只做一个请求,所以我打算使用类似于trampoline调度程序的线程队列调度程序。

现在我尝试实现一种机制来监视服务器上的更改。因此,我发送一个长期生存请求,阻止服务器进行一些更改并发回结果(长拉)。

此长拉取请求应仅在作业队列空闲时运行。我正在寻找一种在计划常规请求时自动停止监视请求的方法,并在队列变空时再次启动它。我想过修改trampoline调度程序以获得这种行为,但我觉得这是一个常见的问题,可能有一个更简单的解决方案?

1 个答案:

答案 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();
        }
    }
}