Java Mq和Native Mq之间的关系

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第15天,点击查看活动详情

相关名词

mq:消息队列MessageQuene的缩写

流程

java的mq初始化的时候会先初始化native的mq再native的mq中又创建了native层的looper。同时native层把自己mq传入到了java中mq的mptr对象

java消息队列中调用nativepollonce(javaMq中的next方法)最终会调用到mtpr的nativepollonce(mtpr是native层的消息队列对象)该方法用于等待一个java层的消息来临

native的mq的nativepollonce会调用looper的pollonce方法(这个looper是native层的)

pollonce方法中会取出responce(其他监听的fd来的request封装的)处理

接着会调用pollinner。 pollinner才是真正决定是否有消息处理的地方。 pollinner中会等待pipe唤醒(代表有消息来了需要处理),唤醒之后查看是否是消息来还是其他fd发出的request。

之后

取出管道的事件进行处理,先处理native的消息。

fd发出的request:对其封装成一个response。添加到mresponse数组中。 等待native消息处理完后再取出response数组处理监听fd得到的事件。

最后返回java的消息回到java的nativepollonce方法中。

java和native中都是利用handler发消息,都是调用的管道流进行唤醒。

java层的next会调用nativepollonce进入到native的消息队列中,native层looper的pollinner实现阻塞。(唤醒可能是由于消息或者fd发生request)。

为fd的request创建对应response添加到response数组中,等待native的消息处理完,在处理request,接着返回到java的消息。java的mq恢复处理。

注意点

根据上面的分析流程我们可以知道,即使CPU充足堆栈情况正常也不能一定保证java发出的消息可以按计划得到执行。这个时候很有可能是native在处理自己的消息或者在native中对监听到的fd做处理,最后才会轮到java中的消息处理。nativePollonce才因此返回进入java消息处理过程。

mq为什么采用epoll机制?

select和epoll机制区别:

1.关于监听fd的复制次数

select每次调用都需要将监听的事件复制到内核中。而epoll只需要在epllctl进行加入操作时才复制一份

2.效率问题

epoll使用红黑树保存监听事件,而select内部使用数组存储(监听事件数量有限10个)。当监听事件变得多时select效率没有epoll好,但是当事件少时两者查找效率差不多

epoll和pipe区别

epoll等待监听事件触发。等待监听的fd和对应接受的动作

使用pipe用于唤醒,使用pipe用作线程间通信的原因是因为:写端发送的数据读端不感兴趣,只做简单的唤醒,无需对数据处理,因此使用pipe读端不关心数据只起到唤醒作用

猜你喜欢

转载自juejin.im/post/7086989611469127710
MQ
今日推荐