这两天学员朋友们在vip群都在讨论google官方发布的blog:安卓17版本上google引入了无锁消息队,提升手机流畅度的文章。
原文地址(可能国内无法访问):
https://android-developers.googleblog.com/2026/02/under-hood-android-17s-lock-free.html
谷歌在2026年宣布,安卓17系统将通过引入DeliQueue系统显著提升手机的流畅度,减少用户在日常操作中遇到的卡顿和滑动不流畅问题。新系统的核心改进在于优化了MessageQueue的内存锁定机制,从而缩短了软件线程之间的等待时间。

底层原理:Android17 的无锁消息队
Under the hood: Android 17's lock-free MessageQueue
学员提出疑问:
请问具体MessageQueue中的锁具体在哪里体现的呢?马哥方便贴出一下相关的源码么,只是看到文章写的MessageQueue有锁竞争,但是没注意看哪里有锁,还有MessageQueue应该也还有native代码吧,也有锁么?

下面来带大家剖析一下MessageQueue的相关锁到底在哪里,对相关源码进行剖析。
正常java端进行发送消息,都是只需要有一个Handler调用sendMessage方法就可以,不管任何线程都可以调用Handler的sendMessage方法进行消息发送。
frameworks/base/core/java/android/os/Handler.java
/** * Pushes a message onto the end of the message queue after all pending messages * before the current time. It will be received in {@link #handleMessage}, * in the thread attached to this handler. * * @return Returns true if the message was successfully placed in to the * message queue. Returns false on failure, usually because the * looper processing the message queue is exiting. */publicfinal boolean sendMessage(@NonNull Message msg){return sendMessageDelayed(msg, 0); }注意:post消息其实也是最后调用到了sendMessage相关方法
/** * Causes the Runnable r to be added to the message queue. * The runnable will be run on the thread to which this handler is * attached. * * @param r The Runnable that will be executed. * * @return Returns true if the Runnable was successfully placed in to the * message queue. Returns false on failure, usually because the * looper processing the message queue is exiting. */publicfinal boolean post(@NonNull Runnable r){return sendMessageDelayed(getPostMessage(r), 0); }这里会调用到sendMessageDelayed
publicfinal boolean sendMessageDelayed(@NonNull Message msg, long delayMillis){if (delayMillis < 0) { delayMillis = 0; }return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); }这里又会调用到sendMessageAtTime方法
public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis){ MessageQueue queue = mQueue;return enqueueMessage(queue, msg, uptimeMillis);//调用到enqueueMessage }再看看enqueueMessage方法
private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,long uptimeMillis){ msg.target = this; msg.workSourceUid = ThreadLocalWorkSource.getUid();if (mAsynchronous) { msg.setAsynchronous(true); }returnqueue.enqueueMessage(msg, uptimeMillis);//这里最后调用到MessageQueue的enqueueMessage方法 }再看看MessageQueue的enqueueMessage方法:
frameworks/base/core/java/android/os/MessageQueue.java
boolean enqueueMessage(Message msg, long when){if (msg.target == null) {thrownew IllegalArgumentException("Message must have a target."); } synchronized (this) {//这里是锁 msg.markInUse(); msg.when = when; Message p = mMessages; boolean needWake;if (p == null || when == 0 || when < p.when) {// New head, wake up the event queue if blocked. msg.next = p; mMessages = msg; needWake = mBlocked; } else {// Inserted within the middle of the queue. Usually we don't have to wake// up the event queue unless there is a barrier at the head of the queue// and the message is the earliest asynchronous message in the queue. needWake = mBlocked && p.target == null && msg.isAsynchronous(); Message prev;for (;;) { prev = p; p = p.next;if (p == null || when < p.when) {break; }if (needWake && p.isAsynchronous()) { needWake = false; } } msg.next = p; // invariant: p == prev.next prev.next = msg; }// We can assume mPtr != 0 because mQuitting is false.if (needWake) { nativeWake(mPtr); } }returntrue; }看看native层面如何发送Message
可以看到主要调用是sendMessage方法 system/core/libutils/Looper.cpp
voidLooper::sendMessage(const sp<MessageHandler>& handler, const Message& message){nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); sendMessageAtTime(now, handler, message);}在看看sendMessageAtTime方法
voidLooper::sendMessageAtTime(nsecs_t uptime, const sp<MessageHandler>& handler,const Message& message){size_t i = 0; { // acquire lock AutoMutex _l(mLock);//这里也有一个锁保护size_t messageCount = mMessageEnvelopes.size();while (i < messageCount && uptime >= mMessageEnvelopes.itemAt(i).uptime) { i += 1; }MessageEnvelope messageEnvelope(uptime, handler, message); mMessageEnvelopes.insertAt(messageEnvelope, i, 1);// Optimization: If the Looper is currently sending a message, then we can skip// the call to wake() because the next thing the Looper will do after processing// messages is to decide when the next wakeup time should be. In fact, it does// not even matter whether this code is running on the Looper thread.if (mSendingMessage) {return; } } // release lock// Wake the poll loop only when we enqueue a new message at the head.if (i == 0) { wake(); }}可以看到在 Looper::sendMessageAtTime方法中对mMessageEnvelopes进行操作时候都是有lock进行保护的。
更多vip免费系统开发经典大厂面试题库获取,课程优惠购买成为vip学员进入vip群,积极讨论各种行业难点痛点疑难问题,答疑服务等。
请联系马哥微信:
