为了账号安全,请及时绑定邮箱和手机立即绑定

如何避免事件驱动 Java 中繁忙的 while 循环

如何避免事件驱动 Java 中繁忙的 while 循环

慕仙森 2023-10-12 16:43:30
我目前正在按以下方式开发事件驱动的 Java 软件(这是我的主要方法的本质):while(true) {    Event event = eventListener.poll();    if(event != null) {        // do something    } else {        // do nothing as usual, but burn CPU time.    }}根据我正在构建的内容,eventListener可能会监听外部 websocket、轮询 Redis 通道以获取更新,或者等待来自同一盒子上的另一个进程的消息(可能通过 UDP/TCP/shm)。eventListener我的想法是,这种繁忙的循环方法在返回 null 时(大多数情况下)会浪费大量 CPU 时间,因为它只是坐在那里旋转。但是,除了每次迭代之外,我不知道如何实现此设计,Thread.sleep这不是一个很好的解决方案。理想情况下我想要一个方法:void run(Event event) {    // do something}run每当事件发生时都会调用where eventListener。如果没有这样的事件可用,则理想情况下该过程应该只是闲置。现在,我知道有一些 websocket 库实际上可以做到这一点,我想知道的是我如何为自己构建这样的东西,并将我的 CPU 从坐在那里浪费自己无所事事的状态中解放出来?
查看完整描述

2 回答

?
慕姐4208626

TA贡献1852条经验 获得超7个赞

您需要使用java非阻塞IO,并且可能是一些支持通过java NIO进行高级通信的库(例如netty,它支持HTTP、websockets和redis等的NIO风格通信)。

以下是 NIO 工作原理的简短描述。你正在寻找的东西是Selector. 它允许等待通道(这是文件或网络连接等的抽象)上的数据可用。此 wait(Selector.select方法) 是阻塞的,当某些数据可供读取或要写入的输出缓冲区可以获得新数据时,操作系统会恢复该进程。

代码大致如下所示:

Selector selector = createSelector();

Channel channel = createChannelForSocket();


SelectionKey key = channel.register(selector);


while(true) {


  int readyChannels = selector.select(TIMEOUT);


  if(readyChannels == 0) continue;


  Set<SelectionKey> selectedKeys = selector.selectedKeys();


  for(SelectionKey key : selectedKeys) {


    if (key.isReadable()) {

        readDataFromChannel(key.channel())

    } else if (key.isWritable()) {

        writeDataToChannel(key.channel())

    }


  }

}

使用netty,您可以拥有更高级别的代码,您可以在其中定义一个Handlerwhich,它有一个类似于which的方法void channelRead(ChannelHandlerContext ctx, Object msg),它是一种读取事件侦听器,您可以实现它来侦听读取事件。


netty 有一个内置循环,看起来与上面的示例类似,但对于许多事件侦听器来说,它将这些事件传播到特定的侦听器。


查看完整回答
反对 回复 2023-10-12
?
aluckdog

TA贡献1847条经验 获得超7个赞

如果您有兴趣大规模使用事件驱动架构。您可能想要使用强大的“事件总线”,例如 Apache Kafka 或 AWS SNS+SQS。为了更简单,您可以使用 kalium.alkal.io。这将无缝处理 POJO 或 protobuf 对象的反/序列化。


kalium.on(Event.class, event -> {


   //doSomething with the event

});


查看完整回答
反对 回复 2023-10-12
  • 2 回答
  • 0 关注
  • 75 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信