最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java?Handler同步屏障淺析講解

 更新時間:2022年08月29日 08:38:46   作者:niuyongzhi  
同步屏障機制是什么?Handler發(fā)送的消息分為普通消息、屏障消息、異步消息,一旦Looper在處理消息時遇到屏障消息,那么就不再處理普通的消息,而僅僅處理異步的消息。不再使用屏障后,需要撤銷屏障,不然就再也執(zhí)行不到普通消息了

1.在View的加載和繪制流程這篇文章中:傳送門,有一個編舞者類,mChoreographer。 

mTraversalBarrier = mHandler.getLooper().postSyncBarrier();向MessageQueue中插入一條同步屏障消息,msg.target==null的消息,返回值mTraversalBarrier是一個int 的token值。

  void scheduleTraversals() {
    if (!mTraversalScheduled) {
      mTraversalScheduled = true;
       //向消息隊列插入一個同步屏障的消息。msg.target==null的消息
             mTraversalBarrier = mHandler.getLooper().postSyncBarrier();
             mChoreographer.postCallback(
                  Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
    }
  }

mChoreographer.postCallback()方法會執(zhí)行mTraversalRunnable中的代碼。

mHandler.getLooper().removeSyncBarrier(mTraversalBarrier);這個會根據(jù)上面產(chǎn)生的token值移出MessageQueue中的同步屏障消息。

 final TraversalRunnable mTraversalRunnable = new TraversalRunnable();
 final class TraversalRunnable implements Runnable {
            @Override
            public void run() {
                doTraversal();
            }
  }
   void doTraversal() {
      if (mTraversalScheduled) {
          mTraversalScheduled = false;
          //移除同步屏障消息
          mHandler.getLooper().removeSyncBarrier(mTraversalBarrier);
          //在這個方法中會調(diào)用 measure layout draw,view的繪制繪制流程的方法
          performTraversals();
      }
    }

還是看這行代碼mHandler.getLooper().postSyncBarrier(),系統(tǒng)是怎么處理的。

獲取了一個沒有設(shè)置handler的Message。

int enqueueSyncBarrier(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++;
            // 這個msg.target沒有被賦值
            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;
        }
    }

正常我們通過handler發(fā)送消息,handler是不允許為空的。

 boolean enqueueMessage(Message msg, long when) {
        if (msg.target == null) {
            throw new IllegalArgumentException("Message must have a target.");
        }
   ...........
}

那系統(tǒng)為啥要發(fā)送一個handler為空的消息呢?

先看mChoreographer發(fā)了同步屏障消息后,又做了什么?

又發(fā)送了一個異步消息:msg.setAsynchronous(true),這個消息的handler不為null。

private void postCallbackDelayedInternal(int callbackType,
            Object action, Object token, long delayMillis) {
      synchronized (mLock) {
            final long now = SystemClock.uptimeMillis();
            final long dueTime = now + delayMillis;
            mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token);
            if (dueTime <= now) {
                scheduleFrameLocked(now);
            } else {
                Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_CALLBACK, action);
                msg.arg1 = callbackType;
                //將消息設(shè)置為異步消息
                msg.setAsynchronous(true);
                mHandler.sendMessageAtTime(msg, dueTime);
            }
        }
}

接下來看看MessageQueue是怎么去消息的,是如何對這個同步屏障消息怎么處理的。

 Message next() {
            synchronized (this) {
                // Try to retrieve the next message.  Return if found.
                final long now = SystemClock.uptimeMillis();
                Message prevMsg = null;
                Message msg = mMessages;
                //如果msg.target==null說明我們已經(jīng)向消息隊里中插入了一條屏障消息。
                //此時會進(jìn)入到這個循環(huán)中,找到msg.isAsynchronous==true的異步消息。
                //通常我們發(fā)送的都是同步消息isAsynchronous = false的,并且msg.target不能為null的。
                if (msg != null && msg.target == null) {
                    // Stalled by a barrier.  Find the next asynchronous message in the queue.
                    do {
                        prevMsg = msg;
                        msg = msg.next;
                    } while (msg != null && !msg.isAsynchronous());//msg.isAsynchronous==true時結(jié)束循環(huán),說明找到了這個異步消息。
                }
                if (msg != null) {//找到了同步屏障的異步消息后,直接返回
                    if (now < msg.when) {
                        // Next message is not ready.  Set a timeout to wake up when it is ready.
                        nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
                    } else {
                        // Got a message.
                        mBlocked = false;
                        if (prevMsg != null) {
                            prevMsg.next = msg.next;
                        } else {
                            mMessages = msg.next;
                        }
                        msg.next = null;
                        if (false) Log.v("MessageQueue", "Returning message: " + msg);
                        return msg;
                    }
                } else {//沒有找到的話則進(jìn)入休眠直到下一次被喚醒
                    // No more messages.
                    nextPollTimeoutMillis = -1;
                }
        }
    }

在取消的時候,先判斷進(jìn)行msg.target為null的判斷,然后經(jīng)過while循環(huán),找到msg.isAsynchronous() == true的消息。也就是上面發(fā)送的異步消息。通常我們發(fā)送的消息都是同步消息,不會對對 msg.setAsynchronous(true);進(jìn)行設(shè)置。

系統(tǒng)這樣做的目的就是為了優(yōu)先去處理這個異步消息。會把所有的同步消息放在后面,向一道屏障一樣,所以這樣的操作,被稱為同步屏障,是同步屏障消息的處理有更高的優(yōu)先級。

因為編舞者類mChoreographer 負(fù)責(zé)屏幕的渲染,需要及時的處理從底層過來的信號,以保障界面刷新的頻率。

那么mChoreographer是如何處理信號的,如何進(jìn)行渲染的邏輯是怎么樣的,有機會再寫文章進(jìn)行分享。

到此這篇關(guān)于Java Handler同步屏障淺析講解的文章就介紹到這了,更多相關(guān)Java Handler內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中synchronized的幾種使用方法

    Java中synchronized的幾種使用方法

    本文主要介紹了Java中synchronized的幾種使用方法,synchronized可用于修飾普通方法、靜態(tài)方法和代碼塊,下面詳細(xì)內(nèi)容介紹,需要的小伙伴可以參考一下
    2022-05-05
  • 手把手帶你入門 Spring Security的具體流程

    手把手帶你入門 Spring Security的具體流程

    這篇文章主要介紹了手把手帶你入門 Spring Security,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • 基于JAVA代碼 獲取手機基本信息(本機號碼,SDK版本,系統(tǒng)版本,手機型號)

    基于JAVA代碼 獲取手機基本信息(本機號碼,SDK版本,系統(tǒng)版本,手機型號)

    本文給大家介紹基于java代碼獲取手機基本信息,包括獲取電話管理對象、獲取手機號碼、獲取手機型號、獲取SDK版本、獲取系統(tǒng)版本等相關(guān)信息,對本文感興趣的朋友一起學(xué)習(xí)吧
    2015-12-12
  • Java判斷當(dāng)前日期是周幾的方法匯總

    Java判斷當(dāng)前日期是周幾的方法匯總

    在Java編程中,我們經(jīng)常會遇到需要獲取當(dāng)前日期是周幾的需求。根據(jù)國際慣例,一周通常是從周一開始,到周日結(jié)束,記作1至7,本文將介紹幾種常用的Java方法,讓你能夠準(zhǔn)確地判斷當(dāng)前日期是周幾,感興趣的朋友一起看看吧
    2024-03-03
  • Cookie 實現(xiàn)的原理

    Cookie 實現(xiàn)的原理

    我們在瀏覽器中,經(jīng)常涉及到數(shù)據(jù)的交換,比如你登錄郵箱,登錄一個頁面。我們經(jīng)常會在此時設(shè)置30天內(nèi)記住我,或者自動登錄選項。那么它們是怎么記錄信息的呢,答案就是今天的主角cookie了
    2021-06-06
  • Ribbon負(fù)載均衡算法原理與使用介紹

    Ribbon負(fù)載均衡算法原理與使用介紹

    在微服務(wù)中,對服務(wù)進(jìn)行拆分之后,必然會帶來微服務(wù)之間的通信需求,而每個微服務(wù)為了保證高可用性,又會去部署集群,那么面對一個集群微服務(wù)進(jìn)行通信的時候,如何進(jìn)行負(fù)載均衡也是必然需要考慮的問題
    2022-09-09
  • java實現(xiàn)  微博登錄、微信登錄、qq登錄實現(xiàn)代碼

    java實現(xiàn) 微博登錄、微信登錄、qq登錄實現(xiàn)代碼

    這篇文章主要介紹了java實現(xiàn) 微博登錄、微信登錄、qq登錄實現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下
    2016-10-10
  • Spring Cloud Gateway全局異常處理的方法詳解

    Spring Cloud Gateway全局異常處理的方法詳解

    這篇文章主要給大家介紹了關(guān)于Spring Cloud Gateway全局異常處理的相關(guān)資料,需要的朋友可以參考下
    2018-10-10
  • SpringCloud微服務(wù)調(diào)用丟失請求頭的問題及解決方案

    SpringCloud微服務(wù)調(diào)用丟失請求頭的問題及解決方案

    在Spring Cloud 中微服務(wù)之間的調(diào)用會用到Feign,但是在默認(rèn)情況下,Feign 調(diào)用遠(yuǎn)程服務(wù)存在Header請求頭丟失問題,下面給大家分享SpringCloud微服務(wù)調(diào)用丟失請求頭的問題及解決方案,感興趣的朋友一起看看吧
    2024-02-02
  • java同步器AQS架構(gòu)AbstractQueuedSynchronizer原理解析

    java同步器AQS架構(gòu)AbstractQueuedSynchronizer原理解析

    這篇文章主要為大家介紹了java同步器AQS架構(gòu)AbstractQueuedSynchronizer的底層原理及源碼解析,有需要的朋友可以借鑒參考下,希望能有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-03-03

最新評論

蒲城县| 寻甸| 顺义区| 山丹县| 宜阳县| 泊头市| 文山县| 武汉市| 大港区| 高阳县| 文成县| 金塔县| 晋中市| 乌海市| 濉溪县| 牙克石市| 桃江县| 定州市| 阿巴嘎旗| 三穗县| 石城县| 本溪市| 武陟县| 肃南| 吴堡县| 青河县| 大英县| 衡东县| 陆丰市| 海城市| 柘荣县| 浦北县| 油尖旺区| 隆安县| 富源县| 定日县| 洛宁县| 吴旗县| 阿拉尔市| 乌拉特前旗| 库伦旗|