Observer pattern: Defines a one-to-many dependency between objects so that every time an object changes state, all objects that depend on it are notified and updated automatically.
EventBus (Event Bus) in Guava framework is an implementation of the observer pattern.
EventBus is an excellent way to achieve loose coupling within a single architecture, through which event registration, monitoring and consumption can be implemented very succinctly.
The Guava framework provides two time buses: EventBus (synchronous) and AsyncEventBus (asynchronous, inherited from EventBus):
1. Single-threaded synchronous event consumption
2. Multithread Asynchronous Event Consumption
Guava default subscriber's consumption method does not have concurrency capability. If your consumption method has concurrency capability, you can use the @AllowConcurrent Events annotation to mark that the current subscriber is thread-safe and supports concurrent receipt of event messages.
When the parameter type of the subscription method (the method modified by @Subscribe) is consistent with that of the event publisher, the message is received and consumed. If an event post ed by the event publisher is not subscribed to, the change time will be decorated as DeadEvent and processed by the corresponding DeadEvent subscriber.
import com.google.common.eventbus.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * @ClassName: EventBusTest * @Description: TODO * @Author: RuiXin Yu * @Date: 2019/9/19 20:59 */ public class EventBusTest { private static class Event1 { @Override public String toString() { return "Event 1"; } } private static class Event2 { @Override public String toString() { return "Event 2"; } } private static class EventX { @Override public String toString() { return "Event X"; } } private static class EventListener { @Subscribe @AllowConcurrentEvents public void onEvent(Event1 event1) throws InterruptedException { String name = Thread.currentThread().getName(); System.out.println(name + " sleep A little while"); Thread.sleep(1000); System.out.println(name + "===Subscription Event 1,Receive:" + event1); } @Subscribe public void onEvent(Event2 event2) throws InterruptedException { String name = Thread.currentThread().getName(); System.out.println(name + " sleep A little while"); Thread.sleep(1000); System.out.println(name + "===Subscription Event 2,Receive:" + event2); } @Subscribe public void onEvent(DeadEvent deadEvent) throws InterruptedException { String name = Thread.currentThread().getName(); Thread.sleep(10*1000); System.out.println(name + "===Subscription error events,Receive:" + deadEvent); } } public static void main(String[] args) throws InterruptedException { String name = Thread.currentThread().getName(); EventBus eb = new EventBus(); eb.register(new EventListener()); System.out.println(name + "----------Sending events X---------"); eb.post(new EventX()); System.out.println(name + "----------Send Event 1----Parallel reception-----"); ExecutorService threadPool = Executors.newCachedThreadPool(); eb = new AsyncEventBus(threadPool); eb.register(new EventListener()); for (int i = 0; i < 10; i++) { eb.post(new Event1()); } Thread.sleep(2000); System.out.println(name + "----------Send Event 2----Serial reception-----"); for (int i = 0; i < 10; i++) { eb.post(new Event2()); } Thread.sleep(2000); threadPool.shutdown(); } }
Console Printing
main - ---------------------------------------------------------------------------------------------------------------------------- main=== Subscribe to the wrong event and receive DeadEvent{source=EventBus{default}, event = Event X} main ------ send event 1--------- pool-1-thread-1 sleep for a while pool-1-thread-2 sleep for a while pool-1-thread-3 sleep for a while pool-1-thread-4 sleep for a while pool-1-thread-5 sleep for a while pool-1-thread-6 sleep for a while pool-1-thread-7 sleep for a while pool-1-thread-8 sleep for a while pool-1-thread-9 sleep for a while pool-1-thread-10 sleep for a while pool-1-thread-1====subscribe to event 1 and receive: event 1 pool-1-thread-2====subscribe to event 1 and receive: event 1 pool-1-thread-3====subscribe to event 1 and receive: event 1 pool-1-thread-4====subscribe to event 1 and receive: event 1 pool-1-thread-5====subscribe to event 1 and receive: event 1 pool-1-thread-7====subscribe to event 1 and receive: event 1 pool-1-thread-6====subscribe to event 1 and receive: event 1 pool-1-thread-8====subscribe to event 1 and receive: event 1 pool-1-thread-9====subscribe to event 1 and receive: event 1 pool-1-thread-10===subscribe to event 1 and receive: event 1 main------------------------------------------------------------------------------------------------------------ Sending Event 2 pool-1-thread-9 sleep for a while pool-1-thread-9====subscribe to event 2 and receive: event 2 pool-1-thread-2 sleep for a while pool-1-thread-2====subscribe to event 2 and receive: event 2 pool-1-thread-5 sleep for a while pool-1-thread-5====subscribe to event 2 and receive: event 2 pool-1-thread-3 sleep for a while pool-1-thread-3====subscribe to event 2 and receive: event 2 pool-1-thread-4 sleep for a while pool-1-thread-4====subscribe to event 2 and receive: event 2 pool-1-thread-1 sleep for a while pool-1-thread-1====subscribe to event 2 and receive: event 2 pool-1-thread-7 sleep for a while pool-1-thread-7====subscribe to event 2 and receive: event 2 pool-1-thread-6 sleep for a while pool-1-thread-6====subscribe to event 2 and receive: event 2 pool-1-thread-8 sleep for a while pool-1-thread-8====subscribe to event 2 and receive: event 2 pool-1-thread-10 sleep for a while pool-1-thread-10====subscribe to event 2 and receive: event 2