Java – guava eventbus scheduling

I use guava's eventbus to start some processing and report results This is a very simple compiled example:

import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;

public class Test {

    public static class InitiateProcessing { }
    public static class ProcessingStarted { }
    public static class ProcessingResults { }
    public static class ProcessingFinished { }

    public static EventBus bus = new EventBus();

    @Subscribe
    public void receiveStartRequest(InitiateProcessing evt) {
        System.out.println("Got processing request - starting processing");
        bus.post(new ProcessingStarted());

        System.out.println("Generating results");
        bus.post(new ProcessingResults());
        System.out.println("Generating more results");
        bus.post(new ProcessingResults());

        bus.post(new ProcessingFinished());
    }

    @Subscribe
    public void processingStarted(ProcessingStarted evt) {
        System.out.println("Processing has started");
    }

    @Subscribe
    public void resultsReceived(ProcessingResults evt) {
        System.out.println("got results");
    }

    @Subscribe
    public void processingComplete(ProcessingFinished evt) {
        System.out.println("Processing has completed");
    }


    public static void main(String[] args) {
        Test t = new test();
        bus.register(t);
        bus.post(new InitiateProcessing());
    }
}

I use these events as a way for other software components to react and prepare for this processing For example, they may have to save their current state before processing and restoring

I expect the output of this program to be:

Got processing request - starting processing
Processing has started
Generating results
got results
Generating more results
got results
Processing has completed

Instead, the actual output is:

Got processing request - starting processing
Generating results
Generating more results
Processing has started
got results
got results
Processing has completed

The event that should indicate the start of processing actually occurred after the actual processing ("generated result")

After reading the source code, I understand why This is the source code related to eventbus

/**
   * Drain the queue of events to be dispatched. As the queue is being drained,* new events may be posted to the end of the queue.
   */
  void dispatchQueuedEvents() {
    // don't dispatch if we're already dispatching,that would allow reentrancy
    // and out-of-order events. Instead,leave the events to be dispatched
    // after the in-progress dispatch is complete.
    if (isDispatching.get()) {
        return;
    }
    // dispatch event (omitted)

What happened is that I have published the top-level initiateprocessing event, and the rest of the events are pushed to the end of the queue I hope this is similar to The NET event does not return the event before all the processors are completed.

I don't quite understand the reason for this realization Of course, these events are guaranteed, but the order of the surrounding code is completely distorted

Is there a way for the bus to operate as described and produce the required output? I've seen it in Javadoc

But I don't think this applies here - I see this problem in a single threaded application

edit

The reason for this problem is that I publish from subscribers Since the event bus is not reentrant, these "child positions" will be queued and processed after the first handler completes I can comment out if (isdispatching. Get()) {return;} Partly in the eventbus source, everything is as I expected - so the real question is what potential problems do I introduce by doing so? The designer seems to have made a serious decision not to allow re - admission

Solution

Eventbus usually follows the principle that the code that publishes events to the bus should not care what users do to events or be respected (in the case of synchronous events)

If you want to call a specific method at a specific time of the method and want to ensure that these methods are completed before the method continues (as you are in the example), why not call these methods directly? When you use the event bus, you explicitly separate the code from the response to a given event that occurs correctly This is desirable in many cases and is the main reason for the existence of eventbus, but it does not seem to be the same

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>