Java 什么';番石榴中的即食和即食番石榴有什么区别?

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

ImmediateDispatcher的dispatch()方法是:

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();
}
}
}
我对这种方法有疑问:

  • 将事件和订阅服务器封装到事件对象中并提供给threadlocal队列,然后轮询它以执行与ImmediateDispatcher.dispatch()相同的逻辑,这有什么意义
  • 不是分派。get()总是返回false吗?那么为什么会有这样的情况呢

  • 区别在于一个事件触发另一个事件。假设我们有一个触发事件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的回答解释了这对调度命令的影响。