简体   繁体   English

番石榴中的PerThreadQueuedDispatcher和InstantDispatcher有什么区别?

[英]What's the difference between PerThreadQueuedDispatcher and ImmediateDispatcher in guava?

The dispatch() method of ImmediateDispatcher is: InstantDispatcher的dispatch()方法为:

void dispatch(Object event, Iterator<Subscriber> subscribers) {
  checkNotNull(event);
  while (subscribers.hasNext()) {
    subscribers.next().dispatchEvent(event);
  }
}

it just dispatch event to each subscrriber, so this is easy to understand. 它只是将事件分派给每个子用户,所以这很容易理解。

However, the same method of PerThreadQueuedDispatcher is: 但是,PerThreadQueuedDispatcher的相同方法是:

// both queue and dispatching are ThreadLocal.
@Override
void dispatch(Object event, Iterator<Subscriber> subscribers) {
  checkNotNull(event);
  checkNotNull(subscribers);
  Queue<Event> queueForThread = queue.get();
  queueForThread.offer(new Event(event, subscribers)); 
  // Isn't dispatching.get() always return false? Why the if then?
  if (!dispatching.get()) { 
    dispatching.set(true);
    try {
      Event nextEvent;
      while ((nextEvent = queueForThread.poll()) != null) {
        while (nextEvent.subscribers.hasNext()) {
          nextEvent.subscribers.next().dispatchEvent(nextEvent.event);
        }
      }
    } finally {
      dispatching.remove();
      queue.remove();
    }
  }
}

I have questions about this method: 我对此方法有疑问:

  1. What's the point of encapsulating event and subscribers into an Event object and offer it to a threadlocal queue, and then poll it out to perform the same logic that ImmediateDispatcher.dispatch() does? 将事件和订阅者封装到一个Event对象中并提供给线程本地队列,然后对其进行轮询以执行与InstantDispatcher.dispatch()相同的逻辑,这有什么意义呢?
  2. Isn't dispatching.get() always return false? dispatch.get()是否总是返回false吗? Why the if then? 为什么呢?

The difference is when one event triggers another. 区别在于一个事件触发另一个事件。 Suppose we have an event A that triggers events B and C, and event B in turn triggers event D: 假设我们有一个事件A触发了事件B和C,而事件B又触发了事件D:

class Test {
    class A {}
    class B {}
    class C {}
    class D {}

    EventBus bus = new EventBus();

    Test() {
        bus.register(this);
        bus.post(new A());
    }

    @Subscribe void listen(A obj) {
        System.out.println("A");
        bus.post(new B());
        bus.post(new C());
    }

    @Subscribe void listen(B obj) {
        System.out.println("B");
        bus.post(new D());
    }

    @Subscribe void listen(C obj) {
        System.out.println("C");
    }

    @Subscribe void listen(D obj) {
        System.out.println("D");
    }
}

We can think of these events as a sort of tree, where each event spawns additional "child" events: 我们可以将这些事件视为一棵树,其中每个事件都产生其他“子”事件:

    A
   / \
  B   C
 /
D

There are two common ways of traversing a tree: depth-first (A, B, D, C) and breadth-first (A, B, C, D). 遍历树有两种常见的方法:深度优先(A,B,D,C)和宽度优先(A,B,C,D)。 That's the difference between the two dispatchers. 那就是两个调度员之间的区别。

The immediate dispatcher processes events as they're created, resulting in depth-first dispatching. 即时调度程序在创建事件时对其进行处理,从而导致深度优先调度。 The queued dispatcher queues up events as they're submitted and processes them by polling the queue, resulting in breadth-first dispatching. 排队的调度程序将事件提交时排队,并通过轮询队列进行处理,从而导致广度优先的调度。 The dispatching flag is used to restrict queue processing to the root event. dispatching标志用于将队列处理限制为根事件。 Child events will find the flag set and move along. 子事件将找到标志并继续前进。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM