Java 什么';番石榴中的即食和即食番石榴有什么区别?
ImmediateDispatcher的dispatch()方法是:Java 什么';番石榴中的即食和即食番石榴有什么区别?,java,guava,Java,Guava,ImmediateDispatcher的dispatch()方法是: void dispatch(Object event, Iterator<Subscriber> subscribers) { checkNotNull(event); while (subscribers.hasNext()) { subscribers.next().dispatchEvent(event); } } // both queue and dispatching are Th
void dispatch(Object event, Iterator<Subscriber> subscribers) {
checkNotNull(event);
while (subscribers.hasNext()) {
subscribers.next().dispatchEvent(event);
}
}
// 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();
}
}
}
void分派(对象事件、迭代器订阅服务器){
checkNotNull(事件);
while(subscribers.hasNext()){
subscribers.next().dispatchEvent(事件);
}
}
它只是将事件分派给每个子服务器,所以这很容易理解
但是,PerThreadQueuedDispatcher的相同方法是:
void dispatch(Object event, Iterator<Subscriber> subscribers) {
checkNotNull(event);
while (subscribers.hasNext()) {
subscribers.next().dispatchEvent(event);
}
}
// 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();
}
}
}
//队列和分派都是线程本地的。
@凌驾
无效分派(对象事件、迭代器订阅服务器){
checkNotNull(事件);
checkNotNull(订户);
Queue queueForThread=Queue.get();
offer(新事件(事件,订阅者));
//调度.get()不是总是返回false吗?为什么会返回if?
如果(!dispatching.get()){
调度。设置(true);
试一试{
事件下一事件;
而((nextEvent=queueForThread.poll())!=null){
while(nextEvent.subscribers.hasNext()){
nextEvent.subscribers.next().dispatchEvent(nextEvent.event);
}
}
}最后{
dispatching.remove();
queue.remove();
}
}
}
我对这种方法有疑问:
区别在于一个事件触发另一个事件。假设我们有一个触发事件B和C的事件A,事件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,D,C)和广度优先(a,B,C,D)。这就是两个调度员之间的区别
即时调度器在创建事件时处理事件,从而产生深度优先调度。排队的调度器在事件提交时将其排队,并通过轮询队列对其进行处理,从而产生广度优先的调度。
调度
标志用于将队列处理限制为根事件。子事件将找到标志集并继续执行。代码有非常详细的解释@Taylor看起来OP已经在看代码了…@shmosel我知道,但是他的解释(至少第一个问题)就在那里。你似乎错过了关键的东西(仅仅看代码不一定很明显)如果被调用的订户方法发布另一个事件,则循环内的dispatchEvent
调用可能会在同一线程上再次调用dispatch
。这就是调度
的原理@shmosel的回答解释了这对调度命令的影响。