【问题标题】:Posting an event from different thread with Guava EventBus使用 Guava EventBus 从不同线程发布事件
【发布时间】:2017-03-13 15:24:27
【问题描述】:

我在 Vaadin+Spring 项目中使用 Guava Eventbus,并开始遇到从后台线程发布事件的问题。

Eventbus 在包装类中实例化。对象使用主 UI 类中定义的静态方法与事件总线通信,以获取事件总线对象。这与 Vaadin Dashboard 示例 (DashboardEventBus) 中提出的方法相同。

public class MainUI extends UI implements ViewDisplay
{
    private EventBusWrapper eventbus_ = new EventBusWrapper();

    public static EventBusWrapper GetEventBusWrapper()
    {
        return ((MainUI) getCurrent()).eventbus_;
    }
}

问题出现在我创建新线程类并启动线程的演示者/服务类中。 在 run 方法的 Runnable 实现中,我创建了另一个对象来完成一些工作。

public class SearchResultsPresenter extends AbstractPresenter<SearchResultView>
{
    public SearchResultsPresenter()
    {
        EventBusWrapper.register(this);
    }

    @Subscribe
    public void UserSearchRequested(Event.UserSearchRequestEvent e)
    {
        new UpdateContentComponentThread(e.GetSearchElem()).start();
    }

    @Subscribe
    public void UserSearchAppendFoundElement(Event.UserSearchElementFound e)
    {
        if(e.GetElement().IsValid())
            view_.AddElement(e.GetElement());
    }

    public class UpdateContentComponentThread extends Thread
    {
        private final Search searcher_;

        UpdateContentComponentThread(SearchElement search)
        {
            searcher_ = new DefaultSearch(search);
        }

        @Override
        public void run()
        {
           searcher_.Search();
        }
    }
}

它执行一些验证/检查并创建其他帮助类。

public class DefaultSearch implements Search
{
    private final Scraper scraper_;
    ...

    @Override
    public void Search()
    {
        if(!scraper_.IsConfigured())
            return;
        ...
        scraper_.FindElements();
    }
}

然后在 scraper 的 FindElements 主体中,我尝试使用 EventBusWrapper 中定义的静态 post 方法发布事件。

public class HttpElementScraper extends WebScraper
{
    ...

        @Override
        public Collection<Element> FindElements()
        {
            ...
            Element elem = ...
            Event.UserSearchElementFound e = new Event.UserSearchElementFound(elem);
            EventBusWrapper.post(e);

            return foundelements;
        }
    }

此时抛出 NullPointerException,我无法解决问题并帮助自己解决问题。

Exception in thread "Thread-10" java.lang.NullPointerException
    at com.project.MainUI.GetEventBusWrapper(MainUI.java:109)
    at com.project.events.EventBusWrapper.register(EventBusWrapper.java:24)
    at com.project.service.search.scraper.HttpElementScraper.FindElements(HttpElementScraper.java:92)
    at com.project.service.search.DefaultSearch.Search(DefaultSearch.java:38)
    at com.project.view.search.SearchResultsPresenter$UpdateContentComponentThread.run(SearchResultsPresenter.java:71)

// 我省略了不重要的代码行和注释。大多数与之相关的组件和服务都是 UIscoped。

【问题讨论】:

    标签: java multithreading events vaadin guava


    【解决方案1】:

    Vaadin 假定对 Vaadin 组件(和相关)实例的访问已正确同步。当使用传统的单线程请求-响应循环访问组件时,它会自动同步。

    使用外部线程时,您需要使用UI.access() 同步访问您的 Vaadin 组件的代码。例如:

    getUI().access(() -&gt; label.setValue("Hello"));

    【讨论】:

      猜你喜欢
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-03
      • 1970-01-01
      • 1970-01-01
      • 2021-10-03
      • 1970-01-01
      相关资源
      最近更新 更多