当前位置: 首页 > 知识库问答 >
问题:

Guava EventBus调度

姜烨伟
2023-03-14

我正在使用Guava的EventBus启动一些处理并报告结果。下面是一个非常简单的可编译示例:

import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;

public class Test {

    public static class InitiateProcessing { }
    public static class ProcessingStarted { }
    public static class ProcessingResults { }
    public static class ProcessingFinished { }

    public static EventBus bus = new EventBus();

    @Subscribe
    public void receiveStartRequest(InitiateProcessing evt) {
        System.out.println("Got processing request - starting processing");
        bus.post(new ProcessingStarted());

        System.out.println("Generating results");
        bus.post(new ProcessingResults());
        System.out.println("Generating more results");
        bus.post(new ProcessingResults());

        bus.post(new ProcessingFinished());
    }

    @Subscribe
    public void processingStarted(ProcessingStarted evt) {
        System.out.println("Processing has started");
    }

    @Subscribe
    public void resultsReceived(ProcessingResults evt) {
        System.out.println("got results");
    }

    @Subscribe
    public void processingComplete(ProcessingFinished evt) {
        System.out.println("Processing has completed");
    }


    public static void main(String[] args) {
        Test t = new Test();
        bus.register(t);
        bus.post(new InitiateProcessing());
    }
}
Got processing request - starting processing
Processing has started
Generating results
got results
Generating more results
got results
Processing has completed
Got processing request - starting processing
Generating results
Generating more results
Processing has started
got results
got results
Processing has completed
  /**
   * Drain the queue of events to be dispatched. As the queue is being drained,
   * new events may be posted to the end of the queue.
   */
  void dispatchQueuedEvents() {
    // don't dispatch if we're already dispatching, that would allow reentrancy
    // and out-of-order events. Instead, leave the events to be dispatched
    // after the in-progress dispatch is complete.
    if (isDispatching.get()) {
        return;
    }
    // dispatch event (omitted)

发生的情况是,由于我已经分派了顶级initiateprocessing事件,其余的事件只是被推送到队列的末尾。我希望它的行为与.NET事件类似,在该事件中,调用事件直到所有处理程序完成后才返回。

我不太明白这样实现的原因。当然,可以保证事件是有序的,但是周围代码的顺序会被完全扭曲。

有没有什么方法可以让总线按照描述的方式运行并产生所需的输出?我在Javadocs中读到

这里出现问题的原因是我在订阅者内部posting。由于事件总线是不可重入的,所以这些“子帖子”会排队,并在第一个处理程序完成后进行处理。我可以注释掉EventBus源代码中的if(isDispatching.get()){return;}部分,并且所有的行为都与我预期的一样--所以真正的问题是我这样做引入了哪些潜在的问题?看来设计师们做出了不允许重入的认真决定。

共有1个答案

翟昊明
2023-03-14

EventBus通常基于这样一个原则进行操作:将事件发布到总线的代码不应该关心订阅者对事件做了什么或什么时候做了什么,除了遵守事件发布的顺序(在同步事件总线的情况下)。

如果您希望在方法过程中的特定时间调用特定方法,并且希望在方法继续之前确保这些方法完成(就像您在示例中所做的那样),为什么不直接调用这些方法呢?当您使用事件总线时,您将显式地将您的代码与响应给定事件所发生的事情分离开来。这在许多情况下是可取的,也是eventbus存在的主要原因,但在这里似乎并不完全是您想要的。

 类似资料:
  • 通过设置调度标签、调度策略可以实现控制为计算主机提供底层资源的宿主机(物理机)、云账号、网络与存储。 调度标签 调度标签用于与资源进行静态绑定,从而实现资源的调度。 调度策略 调度策略即设置在满足指定条件时,将会根据偏好选择或排除在绑定某一类调度标签的宿主机创建虚拟机。 动态调度标签 动态调度标签即为根据设定的条件在资源调度前动态为宿主机绑定调度标签。

  • 我有以下代码块调用两个请求略有延迟。 在actor1和actor2中,我调用了一个REST请求,该请求返回一个cookie和响应消息。我在这里的意图是延迟发送与actor2对应的REST请求。然而,我从日志中观察到,请求立即从两个参与者发送,只有响应处理(在两个未来之间)延迟10秒。这是Akka中调度器的预期行为吗?如果我想在上述情况下延迟两个参与者之间的请求启动,我可以使用线程。睡觉(我在某个地

  • Storm 现在有 4 种内置的 schedulers(调度器): DefaultScheduler, IsolationScheduler, MultitenantScheduler, ResourceAwareScheduler. Pluggable scheduler(可插拔的调度器) 你可以实现你自己的 scheduler(调度器)来替换掉默认的 scheduler(调度器),自定义分配e

  • 调度器提供了同步递增策略变化的方法。 它应以手工艺等一致性算法为基础,以确保所有执行者的一致性和一致性。 通过调度器用户们可以轻松地建立分布式集群。 调度器的方法分为两部分。 第一种是与Casbin相结合的方法。 这些方法应该在Casbin内部调用。 用户们可以使用由Casbin本身提供的更完整的api。 另一个部分是调度器本身定义的方法,包括调度器初始化方法, 和不同算法提供的不同函数,如动态资

  • 注:本节未经校验,如有问题欢迎提issue 有时需要设定将来发生的事情,这时该怎么办? ActorSystem 就能搞定一切! 在那儿你能找到 scheduler 方法,它返回一个 akka.actor.Scheduler 实例, 这个实例在每个Actor系统里是唯一的,用来在内部指定一段时间后发生的行为。 请注意定时任务是使用 ActorSystem 的 MessageDispatcher 执行

  • Akka MessageDispatcher是维持 Akka Actor “运作”的部分, 可以说它是整个机器的引擎。所有的MessageDispatcher实现也同时也是一个ExecutionContext,这意味着它们可以用来执行任何代码,例如Future(Scala)。 缺省派发器 在没有为Actor作配置的情况下,每一个ActorSystem将有一个缺省的派发器。该缺省派发器可以被配置,默

  • 我刚刚在Codity遇到了一个任务,我找不到目标O(n)效率的解决方案;我的解决方案运行为O(n2)。如果有人能给我一个提示,告诉我如何让它运行得更快,我会非常高兴。这是任务。 给出了一个由N个整数组成的非空零索引数组A。 monotonic_pair是一对整数 (P, Q),使得 0 ≤ P ≤ Q 目标是找到指数相距最远的monotonic_pair。更准确地说,我们应该最大化Q-P值。只找到

  • 解决方案(更新): 我认为任何操作都会导致react-redux-link调用mapState函数,但是当一个操作没有改变任何事情时,情况就不是这样了。 我有一个localStorage模块,它分派操作,但不更改状态,而是写入localStorage。该模块具有容器中使用的选择器,但在状态实际更改之前不会调用这些选择器,因此只有在调度另一个更改状态的操作后,UI才会正确显示。 问题 当我把商店放在