InstantDispatcher的dispatch()方法为:
void dispatch(Object event, Iterator<Subscriber> subscribers) {
checkNotNull(event);
while (subscribers.hasNext()) {
subscribers.next().dispatchEvent(event);
}
}
它只是将事件调度到每个子级,所以这很容易理解。
但是,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();
}
}
}
我对这种方法有疑问
答案 0 :(得分:2)
区别在于一个事件触发另一个事件。假设我们有一个事件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");
}
}
我们可以将这些事件想像成一棵树,其中每个事件都产生其他“子”事件:
A
/ \
B C
/
D
有两种常见的遍历树的方法:深度优先(A,B,D,C)和宽度优先(A,B,C,D)。那是两个调度员之间的区别。
立即调度程序在创建事件时对其进行处理,从而导致深度优先调度。排队的调度程序将事件提交时排队,并通过轮询队列进行处理,从而导致广度优先的调度。 dispatching
标志用于将队列处理限制为根事件。子事件将找到设置的标志并继续前进。