【问题标题】:ExecutorService how to change scheduling clockExecutorService如何更改调度时钟
【发布时间】:2016-02-27 17:44:34
【问题描述】:

我正在使用 Java executorservice 在我的一个应用程序中创建超时效果。经过一段时间后,他们执行服务开始并将用户从他们的会话中注销。但是在 Android 设备上,当设备进入睡眠状态时,执行器线程被挂起。设备唤醒后,线程被取消挂起。我想更改执行程序正在使用的时钟,以便即使在设备进入深度睡眠后它也能继续计数。有没有办法我可以覆盖正在使用的时钟(我意识到我可以换掉整个实现并使用警报管理器,但我希望此时不要更改现有代码,所以请不要尝试提供其他 API)。

我的问题是,尽管设备处于睡眠状态,但必须有一个系统时钟继续运行,我怎样才能让 executor scheduler 使用该时钟而不是它现在使用的时钟,这尊重设备进入深度睡眠和暂停滴答作响?

我目前的代码非常简单,看起来像这样:

myExecutorService.schedule(new EndUserSession(),
                        6L, TimeUnit.MINUTES);

上面的这段代码在 6 分钟内启动 EndUserSession()。它可以工作,但我想使用另一个不考虑移动设备超时的时钟。

【问题讨论】:

    标签: java multithreading executorservice scheduledexecutorservice system-clock


    【解决方案1】:

    我非常怀疑是否有可能影响调度程序服务的计时机制。

    您还有另一种选择来避免设备睡眠引起的问题,例如在构造函数中传递特定时间戳并以固定速率调度任务。示例:

    class EndSessionTask {
    
        final long sessionExpirationTime;
        volatile ScheduledFuture future;
    
        public EndSessionTask(long ts) { sessionExpirationTime = ts; }
    
        public void run() {
            if (sessionExpirationTime < currentTs) return;
            endSession();
            future.cancel();
        }
    
        public void setFuture(ScheduledFuture f) { this.future = f; }
    }
    
    long endSessionTime = System.currentTimeMillis() + 6 * 60 * 1000;
    EndSessionTask task = new EndSessionTask(endSessionTime);
    ScheduledFuture future = executorService.scheduleAtFixedRate(task, 10L, 10L, SECONDS);
    task.setFuture(future);
    

    【讨论】:

    • 你能解释一下10L的逻辑吗?如果不清楚这有什么帮助。设备可以进入睡眠状态,您的日程安排将冻结。当它醒来时,它仍然会继续,如果它被关闭了
    • @j2emanue 这个想法是每 10 秒检查一次会话是否过期。如果设备休眠一小时,任务将在唤醒后 10 秒内触发。它会注意到过期时间已经过去并终止会话。然后它将取消计划任务。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-23
    • 2011-05-13
    • 1970-01-01
    • 1970-01-01
    • 2011-09-01
    相关资源
    最近更新 更多