首页 \ 问答 \ 使用Guava EventBus进行Java多线程处理(Java multithreading with Guava EventBus)

使用Guava EventBus进行Java多线程处理(Java multithreading with Guava EventBus)

我正在使用番石榴事件总线。 我有一个类似服务器的对象,应该一直在运行,监听要发送给我们的事件。 所以在junit测试中(MyObject被测试的类),我在它自己的线程中创建它来模拟这个并阻止阻塞:

  @Test    
  public void test() {
      EventBus eventBus = new EventBus();

      Thread thread= new Thread() {
         @Override
         public void run()
         {
            logger.debug("Creating new thread");
            MyObject myObject = new MyObject(eventBus);
         }
      };

      thread.start();
      ...
  }

一切都很好,myObject是在自己的线程Thread1中创建的。 然后,我在测试中将事件发布到事件总线:

eventBus.post(triggerObject);

我发现的奇怪的事情是我在MyObject类中的订阅方法的所有操作/日志记录都在主线程中再次执行。 myObject等待来自某些其他部分的响应,这会阻止我的测试,因为它在主线程中。 这是为什么发生? 这是我在EventBus或Java线程上做错了吗?


I am using guava event bus. I have a server-like object that is supposed to be running all the time, listening for events to be posted to the b us. So in a junit test (MyObject is class under test), I create it in its own thread to simulate this and prevent blocking:

  @Test    
  public void test() {
      EventBus eventBus = new EventBus();

      Thread thread= new Thread() {
         @Override
         public void run()
         {
            logger.debug("Creating new thread");
            MyObject myObject = new MyObject(eventBus);
         }
      };

      thread.start();
      ...
  }

All is good, myObject is created off in its own thread, Thread1. Then later, I post an event to the event bus in my test:

eventBus.post(triggerObject);

The weird thing I am finding is that all the actions/logging from my subscribed method inside of MyObject class are executing in the main thread again. myObject waits for responses from certain other parts, and this blocks my test since it's in the main thread. Why is this happening? Is it something I am doing wrong with the EventBus or Java threading?


原文:https://stackoverflow.com/questions/25371451
更新时间:2020-01-22 01:21

最满意答案

好吧,你不会在创建的线程中做任何事情,除了创建一个最终在堆中的对象(在线程之间共享),但由于对它的引用是在运行后没有保持,所以它也丢失了。

myObject @Subscribe方法在调用eventBus.post(event);的同一个线程中调用eventBus.post(event); 而不是在创建myObject的线程中。

我发现的奇怪的事情是我在MyObject类中的订阅方法的所有操作/日志记录都在主线程中再次执行

如果你的MyObject类有一个@Subscribe方法,那么为什么它需要构造函数中的一个EventBus实例? 你可能想要

MyObject myObject = new MyObject();
eventBus.register(myObject);`

而不是MyObject myObject = new MyObject(eventBus);


Well you don't do nothing in the created thread except creating an object which finally ends up in heap (which is shared between threads), but since the reference to it is to not maintained after run, then it's also lost.

Your @Subscribe method from myObject is invoked in the same thread that calls eventBus.post(event); and not in the thread that created myObject.

The weird thing I am finding is that all the actions/logging from my subscribed method inside of MyObject class are executing in the main thread again

If your MyObject class has an @Subscribe method, then why does it need an instance of EventBus inside the constructor? You probably want

MyObject myObject = new MyObject();
eventBus.register(myObject);`

instead of MyObject myObject = new MyObject(eventBus);

2014-08-18

相关问答

更多

Guava EventBus:暂停活动发布(Guava EventBus: pause event posting)

我尝试了这种模式,使用子类分类从毒丸模式派生: public class SomethingChangedEvent { private final String name; public SomethingChangedEvent(String name) { this.name = name; } @Override public String toString() { ...

Guava EventBus:如何从事件处理程序返回结果(Guava EventBus: How to return result from event handler)

如果你想要这样的工作流程,你不应该使用Guava EventBus 。 EventBus专门用于允许将事件发布给订阅者,而无需事件发布者知道或关心这些订阅者的内容......因此,您无法将结果返回给订阅者的事件发布者。 这听起来像你应该在这里做更直接的事情,比如注入你的预处理器,persister和验证器并直接调用它们的方法。 If you want a workflow like that, you shouldn't be using a Guava EventBus for it. Even ...

番石榴Eventbus不工作(Guava Eventbus not working)

订阅功能需要公开才能工作。 哎呀 @Subscribe public void testEvent(Object bla) { Log.d("EventBus Event", bla.toString()); } Subscribe functions need to be public to work. Oops @Subscribe public void testEvent(Object bla) { Log.d("EventBus Event", bla.toString ...

使用Guava的EventBus,可以在创建总线的线程上运行用户代码吗?(Using Guava's EventBus, possible to run subscriber code on thread that created the bus?)

在UI应用程序中,有一个运行事件调度循环的线程。 它正在处理用户输入事件和调用处理程序。 通常,UI框架提供了一些在此线程中执行代码的方法,如SwingUtilities.invokeLater(Runnable) AsyncEventBus允许您传递传递Executor,它将为此调用UI框架特定的功能。 这里有几个问题与从android上的工作线程执行UI代码有关。 In UI applications, there is a thread running an event dispatch l ...

Guava EventBus:在GUI应用程序中放置它的位置?(Guava EventBus : where to put it in GUI application?)

事件总线设计模式通常用于Swing应用程序(如其他SO问题中所述 )。 Guava的EventBus只是设计模式的另一个实现,有一些很简单的技巧来简化事件处理(比如使用注释)。 但使用设计模式的目标保持不变。 如果我是你,我会研究如何在富客户端应用程序(在SO / Google上)中使用事件总线模式,同时使用Guava EventBus来简化代码。 EventBus应该是IMO的单身人士(最好通过Google Guice或其他一些DI框架注入)。 我不是Swing dev,但我已经完成了GWT开发 ...

番石榴EventBus:没有注释订阅?(Guava EventBus: Subscribe without annotations?)

番石榴队成员在这里。 非常谨慎的是你只能用@Subscribe注释订阅一个处理程序 - EventBus旨在替换接口,适配器等,而不是补充它们 - 但为什么你说这暴露了更多的实现细节? 根据我们的经验,它通常会减少细节。 Guava team member here. It's quite deliberate that you can only subscribe a handler with the @Subscribe annotation -- EventBus is intended t ...

番石榴EventBus:会/应该与GWT兼容吗?(guava EventBus : would/should this be GWT-compatible?)

对于番石榴讨论而言,这可能比StackOverflow更合适,但番石榴团队成员在这里:不,我们没有计划它。 This is probably more appropriate for guava-discuss than for StackOverflow, but Guava team member here: no, we're not planning on it.

Google Guava EventBus和事件处理程序中的异常(Google Guava EventBus and Exceptions in Event Handlers)

如果你想处理未经检查的异常,你可以像这样实现SubscriberExceptionHandler的方法: public void handleException(Throwable exception, SubscriberExceptionContext context) { // Check if the exception is of some type you wish to be rethrown, and rethrow it. // Here I'll assume ...

使用Guava EventBus进行Java多线程处理(Java multithreading with Guava EventBus)

好吧,你不会在创建的线程中做任何事情,除了创建一个最终在堆中的对象(在线程之间共享),但由于对它的引用是在运行后没有保持,所以它也丢失了。 myObject @Subscribe方法在调用eventBus.post(event);的同一个线程中调用eventBus.post(event); 而不是在创建myObject的线程中。 我发现的奇怪的事情是我在MyObject类中的订阅方法的所有操作/日志记录都在主线程中再次执行 如果你的MyObject类有一个@Subscribe方法,那么为什么它需要 ...

在Google Guava EventBus中引发异常(Bring Up Exceptions in Google Guava EventBus)

以下技巧对我有用: 最新的EventBus类有一个名为handleSubscriberException()的方法,您需要在扩展的EventBus类中重写:(这里我包含了两个解决方案,只有一个适用于您的版本) public class CustomEventBus extends EventBus { //If version 18 or bellow @Override void dispatch(Object event, EventSubscriber wrapper) { ...

相关文章

更多

最新问答

更多
  • 如何保护Solr只允许SELECT请求给用户并禁止其他任何东西?(How to secure Solr to allow SELECT request to only users and disallow anything else?)
  • XPath表达式无效/错误TFHpple SWIFT 1.2(XPath Expression not working/incorrect TFHpple SWIFT 1.2)
  • css3 3D变换不能平滑地制作动画(css3 3D transform doesn't animate smoothly)
  • 运行时错误'91'和Outlook.Application = <对象变量或没有设置块变量>?(Run-time error '91' & Outlook.Application = Object variable or With block variable not set?)
  • 慢的webservice问题(Slow webservice problem)
  • textview的不正确对齐方式(Improper alignment of a textview)
  • 在第一步“Hello World”中出现Java错误(Cannot run “Hello World” program in Eclipse)
  • 为什么十六进制地址是14个字符?(why the hex address is 14 character?)
  • 如何在Python中的不同类中使用变量?(How to use variable in different classes in Python?)
  • asp:GridView HYPERLINKFIELD - datanavigateurlformatstring中的asp代码(asp:GridView HYPERLINKFIELD - asp code inside datanavigateurlformatstring)
  • 关于adaboost算法(About adaboost algorithm)
  • 在Matlab上内置图像(Built in Images on Matlab)
  • java swing:输入键事件时焦点丢失(java swing: Focus lost on enter key event)
  • C#中的通用约束,T是相同的TSomethingElse,对吧?(Generic constraints in C#, T is the same TSomethingElse, right?)
  • 从mybatis中的光标获取数据(Fetching data from cursor in mybatis)
  • 在运行时从XML构建对象的最佳方法(Best way for building objects out of XMLs at runtime)
  • 在整个窗口中拉伸sf :: Sprite(Stretch sf::Sprite across entire window)
  • Selenium Node API Web驱动程序等待超时处理程序(Selenium Node API web driver wait timeout handler)
  • 函数使用并且是map的一部分(循环依赖?)(Function uses and is part of map (circular dependency?))
  • 是否可以在C ++ 14中使用可选模板参数创建类型元组?(Is possible to make a tuple of types with optional template parameters in C++14?)
  • PHP从窗帘后面打印/ f(PHP prints /f from behind the curtains)
  • JFrame的contentPane的LayoutManager(LayoutManager of JFrame's contentPane)
  • 用于Instagram Feed的图像滚动(Image Roll Overs for Instagram Feed)
  • 如何显示拉伸字体(双倍宽度/高度)?(How to display stretched font (double width/height)?)
  • 文件操作API在fileapi.h和stdio.h中的WP8差异?(WP8 differences between file manipulation APIs in fileapi.h and stdio.h?)
  • 保存失败后Rails没有回滚事务()(Rails not rolling back transaction after failed save())
  • jqgrid中的分页问题与数组数据(Pagination problem in jqgrid with array data)
  • 重定向时,通过其他页面上的URL调用javascript函数(Call javascript function through url on otherpage while Redirecting)
  • 如何使用InvokeCommandAction调用我的方法并传入参数?(How do I go about using InvokeCommandAction to call a method of mine and pass in parameters?)
  • Jquerymobile按钮仅显示页面的第一个外观(Jquerymobile buttons are shown only first apperance of the page)