【问题标题】:Singleton, cannot go in the runnable task单例,不能进入可运行任务
【发布时间】:2017-11-13 14:17:38
【问题描述】:

我正在尝试自动运行一项任务(所有 30 多岁)。

为此,我构建了一个单例:

public class PortalSingleton {
    private static final Logger LOG = LoggerFactory.getLogger(PortalSingleton.class);
    private static final int INITIAL_DELAY = 0;
    private static final int DELAY = 30;

    private static volatile ScheduledExecutorService instance;
    private static HomepageView homeView = new HomepageView();

    private PortalSingleton() {}

    public static final void refreshGridHomePageAutomatically() {
        Runnable task = () -> UI.getCurrent().access(() -> {
            homeView.refreshGrid();
            LOG.info("The grid has been refreshed Automatically");
        });
        getInstance().scheduleWithFixedDelay(task, INITIAL_DELAY, DELAY, TimeUnit.SECONDS);
    }

    public final static ScheduledExecutorService getInstance() {
        if (instance == null) {
            synchronized (ScheduledExecutorService.class) {
                if (instance == null) {
                    instance = Executors.newScheduledThreadPool(1);
                }
            }
        }
        return instance;
    }
}

但是,我没有任何问题/错误,而且我没有日志消息,我的网格也没有刷新..

预期的行为是:

  1. 我的网格刷新
  2. 查看日志消息

即使我删除homeView.refreshGrid(); 行,我也没有我的日志消息...

我做错了什么?

谢谢,

编辑:我通过这样做来称呼它:PortalSingleton.refreshGridHomePageAutomatically();

EDIT2,谢谢@Holger:

public class PortalSingleton {
    private static final Logger LOG = LoggerFactory.getLogger(PortalSingleton.class);
    private static final int INITIAL_DELAY = 0;
    private static final int DELAY = 30;

    private static final ScheduledExecutorService instance = Executors.newScheduledThreadPool(1);
    private static HomepageView homeView = new HomepageView();

    private PortalSingleton() {
    }

    public static final void refreshGridHomePageAutomatically() {
        Runnable task = () -> UI.getCurrent().access(() -> {
            homeView.refreshGrid();
            LOG.info("The grid has been refreshed Automatically");
        });
        try {
            getInstance().scheduleWithFixedDelay(task, INITIAL_DELAY, DELAY, TimeUnit.SECONDS);
        } catch (Exception e) {
            LOG.error("error" + e);
        }
    }

    public final static ScheduledExecutorService getInstance() {
        return instance;
    }
}

【问题讨论】:

  • 不抱怨.. 我期待看到消息“网格已自动刷新”并且我的网格已刷新,但我没有预期的行为。所以我不明白我做错了什么,因为,我没有任何错误消息...
  • @Holger,我编辑了我的帖子,清楚了吗?
  • 感谢您的帮助!我尝试对 ScheduledExecutorService 使用 try/catch(请参阅我的帖子中的 EDIT2)。我认为这不好,因为我没有任何错误并且仍然没有预期的行为。
  • 你是对的! NPE!谢谢你的帮助!!!你想把它作为答案吗?我可以关闭这个帖子。

标签: java-8 runnable scheduledexecutorservice vaadin8


【解决方案1】:

当您安排操作时,发生异常时您不会收到反馈。相反,它会停止执行它:

ScheduledExecutorService.scheduleWithFixedDelay(…):

…如果任务的任何执行遇到异常,后续执行将被抑制。

因此,您必须在操作本身中使用 try … catch 块来报告它,例如在定义 Runnable 的 lambda 表达式中:

Runnable task = () -> {
    try { UI.getCurrent().access(…); }
    catch (Exception e) { LOG.error("error" + e); }
};

在我看来,您正在从非 UI 线程调用 UI.getCurrent(),我怀疑它会返回 null,从而在尝试对其调用方法时导致 NullPointerException

【讨论】:

  • 是的,你完全正确:我不应该调用 UI.getCurrent(),我删除了它。我不在用户界面中。当我调试时,我在 UI.getCurrent() 上没有 NPE,但是 NPE 出现了 Try/Catch 再次感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-30
  • 2019-07-07
  • 1970-01-01
  • 2011-03-05
  • 2018-03-18
  • 2011-01-26
  • 1970-01-01
相关资源
最近更新 更多