从观察者模式联想到Java世界的消息传递机制、Akka与Vert.x的消息传递机制

编程入门 行业动态 更新时间:2024-10-27 17:16:57

从观察者模式联想到Java世界的消息传递<a href=https://www.elefans.com/category/jswz/34/1771042.html style=机制、Akka与Vert.x的消息传递机制"/>

从观察者模式联想到Java世界的消息传递机制、Akka与Vert.x的消息传递机制

前言:今天还是有些意外收获的,本来只是在学习观察者模式,想着被观察者的变化是如何通知给观察者的。在自然世界,两个个体之间传递消息,是无需强绑定的,中间总有媒介,比如:面对面交流通过空气传播声音,远程交流通过电话或网络传播信息。而Java世界不同,需要强绑定。那是不是Java世界所有的消息传递都一定要强绑定呢?未必!

首先,我们先来说一说【观察者模式】。设计模式按照解决问题分为三类:创建型(Creational)设计模式、结构型(Structural)设计模式和行为(Behavioral)设计模式,观察者模式(Observer Pattern)属于行为设计模式。

观察者模式需要两个基本抽象对象:被观察者Subject和观察者Observer,被观察者一旦有变化,观察者立马能收到消息(由被观察者发送消息通知)。

之所以为抽象对象,因为我们并不知道被观察者具体为何物,有可能是一个交通灯,有可能是平安银行的股价,也有可能是特快T1的到站情况。观察者亦然,有可能是一个AI摄像头,有可能是具体的某个人,也有可能是接站员。因此在【观察者模式】的类图如下,包括:被观察者和观察者两个接口,被观察者和观察者两个具体实现类,被观察者实现类对象持有多个观察者实现类的对象(这里非常重要,体现了Java世界中的消息传递方式,必须持有被被通知人的对象引用)。

观察者模式的具体实现代码如下:

# 被观察者接口
public interface Subject {void add(Observer observer);void remove(Observer observer);void notify(String message);
}# 观察者接口
public interface Observer {void update(String message);
}# 被观察者【交通灯】对象
public class LightSubject implements Subject{// 此处持有多个观察者对象的引用private List<Observer> observers = new ArrayList<>();@Overridepublic void add(Observer observer) {observers.add(observer);}@Overridepublic void remove(Observer observer) {observers.remove(observer);}@Overridepublic void notify(String message) {for (Observer obs : observers) {// 一旦被观察者变化,则通过调用观察者对象(Observer)对应的方法(update),将message传递给观察者,观察者的update方法则对消息进行处理。obs.update(message);   }}
}# 观察者【摄像头】对象
public class CameraObserver implements Observer{@Overridepublic void update(String message) {if("Green".equals(message)){System.out.println("Go!");}else if("Red".equals(message)){System.out.println("Stop!");}else if("Yellow".equals(message)))){System.out.println("Wait!");}else {System.out.println("I don't know, please wait a moment!");        }}
}# 观察者【人】对象
public class ManObserver implements Observer{@Overridepublic void update(String message) {System.out.println("I'v get what your mean!");        }
}public class ObserverClient {public void cross(){LightSubject subject = new LightSubject();subject.add(new CameraObserver());subject.add(new ManObserver());subject.notify("Green");    //绿灯了subject.notify("Red");    //红灯了subject.notify("Yellow");    //黄灯了}
}

上述代码的第15,16行阐述被观察者持有观察者对象引用是实现观察者模式的基础;第31,32行实现了被观察者将消息传递(通知)给观察者对象。

Java世界消息传递大抵如此:Java语言是面向对象的语言,一个对象向另一个对象传递消息,需要知道对方名字(对象引用)和消息接收通道(对象方法名称),一个对象能够接收很多消息,不同的消息有不同的接收通道。比如:

msg.getMessage("hello"),则向名字为msg的对象发送了一条消息,消息内容为:hello。

由此看出,不论是观察者模式中持有的观察者对象引用,还是这里发送的hello消息,Java世界的消息传递方都需要持有消息接收方对象的引用,这是一种强绑定的消息通知(传递)机制,这种传递机制是同步的。

谈到【消息传递机制】,又联想到两个高性能的并发框架Akka和Vert.x,它们的高性能与它们自身的消息传递机制密不可分。

先来谈谈Akka。Akka是用Scala语言编写的并发框架,其消息传递机制基于Actor模型,Actor是并发计算的最小单元,它们通过发送和接收消息进行通信。当一个消息被发送给一个Actor时,它被放入Actor的邮箱中,然后Actor按照先进先出的顺序处理这些消息。Akka的消息传递模型使用异步非阻塞的方式,这意味着发送消息的操作是非阻塞的,消息不会阻塞发送者或接收者的工作。这使得在高并发场景下,Akka能够处理大量的消息。

为了便于理解,可以把Actor比作一个邮递员,这个邮递员还有一个信件背包,背包用来存放信件,按照收信的先后顺序整理放在这个背包中,信件寄出从背包取信也是按照先收先发原则。由于有了背包空间的缓冲,邮递员可以对收信做出快速响应,信件的后续处理可以按照自己的节奏执行,单线程的处理方式保证了信件的处理顺序,先收到先处理。

与之前提高的Java世界同步的消息传递机制不同的是,Akka中的Actor模型自带了缓冲队列,能够实现异步的消息传递。相同的是,都是强绑定:消息发送方需要持有接收方对象的引用,并调用接收方对象的方法。

public static void main(String[] args) throws java.io.IOException {ActorSystem system = ActorSystem.create("testSystem");ActorRef firstRef = system.actorOf(PrintMyActorRefActor.props(), "first-actor");firstRef.tell("printit", ActorRef.noSender());    //在当前进程内向first-actor发送消息:printittry {System.in.read();} finally {system.terminate();}}

那有没有一种类似文章前言中提到的类似自然世界个人之间消息传递的方式?非强绑定的,通过中间媒介来实现的消息传递方式呢?有,消息队列呀,Vert.x框架的消息传递机制就是类似的原理。

在Vert.x中,消息被发送到一个事件总线(Event Bus),然后这个消息将会被多个消费者同时接收。这个模型允许多个消费者并发地处理消息,提供更高的吞吐量和更好的性能。Vert.x的事件总线是一个中央事件分发器,消息发送方将消息发布到事件总线上,而订阅者则从事件总线上订阅感兴趣的消息。当有消息发布到事件总线上时,所有订阅了这个消息的订阅者都会接收到该消息。

# 消息接收者
public class Receiver extends AbstractVerticle {@Overridepublic void start(){EventBus eb = vertx.eventBus();eb.consumer("ping-address", message -> {System.out.println("Received message: " + message.body());});System.out.println("Receiver ready!");}
}# 消息发送者
public class Sender extends AbstractVerticle {@Overridepublic void start(){EventBus eb = vertx.eventBus();vertx.setPeriodic(1000, v -> {eb.send("ping-address", "ping!");});}
}

Akka与Vert.x消息传递机制的对比:

  1. 并发模型不同:Akka使用Actor模型,而Vert.x使用事件总线模型。Actor模型在处理消息时是单线程的,每个消息都会按照先进先出的顺序依次处理。而事件总线模型允许多个消费者并发地处理消息,因此具有更好的性能。
  2. 消息处理方式不同:在Akka中,每个Actor都有自己的邮箱,消息先进入邮箱,然后按照先进先出的顺序处理。而在Vert.x中,订阅者直接从事件总线上接收消息,而不需要等待消息进入邮箱。这意味着在Vert.x中,消息可以在并发环境下更快地被处理。
  3. 消息传递机制不同:在Akka中,消息是通过Actor之间的直接引用传递的。这意味着在发送消息时,发送方需要知道接收方的引用。而在Vert.x中,消息是通过事件总线发布和订阅的,发送方只需要知道消息的地址,而不需要关心具体的接收方。
  4. 消息处理语义不同:在Akka中,消息接收者可以回复消息给发送者,形成双向通信。而在Vert.x中,事件总线是一种发布-订阅模式,没有直接的回复机制。这意味着在Vert.x中,发送方和接收方之间是一种解耦合的关系。

综上所述,Akka和Vert.x在消息传递模型上存在一些区别。Akka使用Actor模型,采用单线程处理消息,消息通过直接引用传递。而Vert.x使用事件总线模型,允许多个消费者并发地处理消息,消息通过发布和订阅机制传递。根据具体的需求和场景,选择适合的消息传递模型可以提高系统的性能和可扩展性。

总结:阅读完本文,可以了解观察者设计模式是咋回事,观察者是如何接收观察目标变化消息的。基于此引出了Java世界的消息传递机制,在对比阐述了高并发框架Akka和Vert.x的消息传递模型。

更多推荐

从观察者模式联想到Java世界的消息传递机制、Akka与Vert.x的消息传递机制

本文发布于:2024-02-06 18:39:19,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1750898.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:机制   消息   观察者   模式   世界

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!