请谈谈什么是同步屏障?

更多面试题请看这里:https://interview.raoyunsoft.com/

面试题专栏会持续更新欢迎关注订阅

同步屏障是Android消息机制中的一种特殊控制手段,用于临时阻塞同步消息 ,优先处理异步高优先级消息(如UI绘制)。它的核心作用是确保关键任务不被普通消息延迟执行。


一、工作原理

  1. 设置屏障

    调用 handler.getLooper().getQueue().postSyncBarrier() 插入一个 target 为 null 的特殊消息(屏障消息):

    java 复制代码
    // 伪代码实现
    Message barrier = Message.obtain();
    barrier.when = SystemClock.uptimeMillis();
    mQueue.enqueueMessage(barrier); // 屏障入队
  2. 消息处理优先级

    Looper.loop() 执行 queue.next() 时:

    • 遇到屏障消息(target=null)时,跳过所有同步消息
    • 只处理标记为异步的消息(通过 msg.setAsynchronous(true)
  3. 屏障移除

    任务完成后需手动移除屏障:

    java 复制代码
    mQueue.removeSyncBarrier(token); // token是添加屏障时的返回值

二、关键特性

特性 同步消息 异步消息
标记方式 默认状态 msg.setAsynchronous(true)
屏障下的处理 被阻塞 优先执行
典型应用场景 普通业务逻辑 UI绘制、VSync信号响应

三、核心应用场景

View绘制流程 中保证优先级:

java 复制代码
// ViewRootImpl.java
void scheduleTraversals() {
    if (!mTraversalScheduled) {
        mTraversalScheduled = true;
        // 1. 插入同步屏障
        mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
        // 2. 发送异步绘制消息
        mChoreographer.postCallback(
            Choreographer.CALLBACK_TRAVERSAL, 
            mTraversalRunnable, 
            null
        );
    }
}

设计意图:避免用户输入事件(同步消息)阻塞16ms内的UI渲染(异步消息),防止掉帧。


四、底层机制解析

  1. 消息队列结构

    屏障消息如同"闸门",后续同步消息被拦截

  2. next() 关键逻辑

    java 复制代码
    Message next() {
        for (;;) {
            if (msg != null && msg.target == null) {
                // 发现屏障,寻找异步消息
                do {
                    prevMsg = msg;
                    msg = msg.next;
                } while (msg != null && !msg.isAsynchronous());
            }
            return msg; // 只返回异步消息
        }
    }

五、开发者注意事项

  1. 慎用场景

    仅限系统级高优先级任务(如渲染、动画),滥用会导致普通消息饥饿

  2. 屏障必须移除

    未移除的屏障会造成同步消息永久阻塞:

    java 复制代码
    // 在Traversals执行后移除
    void unscheduleTraversals() {
        mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);
    }
  3. 替代方案

    现代开发推荐使用 Choreographer + Vsync 机制管理绘制时序,而非直接操作屏障。

相关推荐
我叫黑大帅8 小时前
MySQL 并发插入竞态问题:原子写入实践指南
后端·mysql·面试
我叫黑大帅9 小时前
别再手动写 updated_at了,这坑我踩过
后端·面试·go
ShineWinsu9 小时前
对于Linux:网络基础的解析
linux·网络·面试·udp·笔试·ip·tcp
咖啡星人k10 小时前
从Vibe Coding到Prompt Engineering:AI编程的新技能树
面试·职场和发展·ai编程
2601_9637713713 小时前
Offloading WP-Cron and Securing Ticket Webhooks on Enterprise IT Sites
android
风止何安啊13 小时前
🚦 前端并发请求 “交通管制”:别让你的接口堵成早高峰
前端·javascript·面试
Fox爱分享14 小时前
字节二面:1000瓶酒,有一瓶是毒药,多少只老鼠可以查出来?
算法·面试·程序员
花燃柳卧14 小时前
跨平台路由组件工程源码补充上传
android·flutter·kotlin
apihz14 小时前
随机驾考题目(C 照科一 / 科四 2000+ 题)免费API调用教程
android·java·c语言·开发语言·网络协议·tcp/ip
Fox爱分享14 小时前
字节二面智力题:100只老虎和1只羊关在一起,这只羊会不会被吃?
算法·面试·程序员