插入代码

public int postSyncBarrier() {
    return postSyncBarrier(SystemClock.uptimeMillis());
}

private int postSyncBarrier(long when) {
    // Enqueue a new sync barrier token.
    // We don't need to wake the queue because the purpose of a barrier is to stall it.
    synchronized (this) {
        final int token = mNextBarrierToken++;
        final Message msg = Message.obtain();
        msg.markInUse();
        msg.when = when;
        msg.arg1 = token;

        Message prev = null;
        Message p = mMessages;
        if (when != 0) {
            while (p != null && p.when <= when) {
                prev = p;
                p = p.next;
            }
        }
        if (prev != null) { // invariant: p == prev.next
            msg.next = p;
            prev.next = msg;
        } else {
            msg.next = p;
            mMessages = msg;
        }
        return token;
    }
}

从贴出的 postSyncBarrier(long when) 方法来看,同步屏障的插入位置取决于 when 参数的值,也就是屏障的触发时间。

来看关键代码:

Message prev = null;
Message p = mMessages;
if (when != 0) {
    while (p != null && p.when <= when) {
        prev = p;
        p = p.next;
    }
}
if (prev != null) { // invariant: p == prev.next
    msg.next = p;
    prev.next = msg;
} else {
    msg.next = p;
    mMessages = msg;
}

结论

同步屏障被插入到 按照 when 时间排序的位置,也就是 整个消息链表中基于时间的合适位置。所以它既不是总在头部也不是总在尾部,而是:

• 如果 when = 0(默认值不是 0),则插入到 消息队列的最前面(头部);

• 如果 when > 0(比如当前时间),则按时间顺序插入到对应位置,可能在头、中或尾部。

举个例子:

如果当前 MessageQueue 中是如下链表:

Message1 (when=1000)
Message2 (when=1050)
Message3 (when=1100)

你调用 postSyncBarrier(SystemClock.uptimeMillis()) 假设当前时间是 1040,则 Barrier 会插入在 Message1 和 Message2 之间。

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器