The problem

  1. PerThreadQueuedDispatcher.dispatch()Encapsulate the Event and subscriber into an Event object and feed it to a thread-local queue, then poll it to perform theImmediateDispatcher.dispatch()What does the same logic mean?
  2. Dispatching. Get () always returns false? Why is that?

The source code section

ImmediateDispatcher#dispatch()

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

PerThreadQueuedDispatcher#dispatch()

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();
    }
  }
}
Copy the code

assumptions

  1. In the same thread, the execution process existsThe eventA nesting phenomenon, in which event A triggers events B and C, and event B triggers event D

validation

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"); }}Copy the code

Think of these events as a kind of tree, each of which produces additional “sub-” events:

    A
   / \
  B   C
 /
D
Copy the code

There are two common ways to traverse A tree: depth-first (A, B, D, C) and breadth-first (A, B, C, D). This is the difference between the two schedulers.

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"); }}Copy the code

We can think of these events as a kind of tree, each of which produces additional “sub-” events:

    A
   / \
  B   C
 /
D
Copy the code

There are two common ways to traverse A tree: depth-first (A, B, D, C) and breadth-first (A, B, C, D). This is the difference between the two schedulers.

The direct scheduler processes events as they are created, resulting in depth-first scheduling.

Perform the following steps: A->B->D->C

The queuing scheduler queues events as they are submitted and processes them by polling the queue, leading to breadth-first scheduling. The Dispatching flag is used to restrict the queue processing to root events. The child event will find the flag set and proceed.

Perform the following steps: A->B->C->D

conclusion

  1. ImmediateDispatcher is a depth-first dynamic in event processing
  2. PerThreadQueuedDispatcher throughdispatchingThe thread performs the sum of flagsqueueForThreadExecution queues are breadth-first scheduling

\