首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

当线程没有阻塞时,为什么还要调用nativeWake()呢?

当线程没有阻塞时,调用nativeWake()的目的是为了确保线程能够立即执行,而不需要等待操作系统的调度。nativeWake()是一种唤醒线程的机制,它可以通过操作系统提供的底层接口直接唤醒线程,使其从等待状态转变为可执行状态。

尽管线程没有阻塞,但在某些情况下,调用nativeWake()仍然是有必要的。以下是几种可能的情况:

  1. 线程调用了sleep()方法:当线程处于睡眠状态时,调用nativeWake()可以立即唤醒线程,使其恢复执行,而不需要等待指定的睡眠时间结束。
  2. 线程调用了wait()方法:当线程处于等待状态时,调用nativeWake()可以立即唤醒线程,使其从等待队列中移出,并开始执行。
  3. 线程调用了join()方法:当线程处于等待其他线程结束的状态时,调用nativeWake()可以立即唤醒线程,使其不再等待,而是继续执行后续的代码。
  4. 线程调用了park()方法:当线程处于被阻塞状态时,调用nativeWake()可以立即唤醒线程,使其恢复执行。

总之,调用nativeWake()可以确保线程在没有阻塞的情况下立即执行,提高线程的响应性和效率。在实际开发中,根据具体的业务需求和线程的状态,合理地使用nativeWake()可以优化线程的运行效果。

腾讯云相关产品和产品介绍链接地址:

  • 云服务器(CVM):https://cloud.tencent.com/product/cvm
  • 云原生应用引擎(TKE):https://cloud.tencent.com/product/tke
  • 人工智能平台(AI Lab):https://cloud.tencent.com/product/ailab
  • 物联网开发平台(IoT Explorer):https://cloud.tencent.com/product/iothub
  • 移动应用开发平台(MPS):https://cloud.tencent.com/product/mps
  • 云数据库 MySQL 版(CDB):https://cloud.tencent.com/product/cdb
  • 腾讯云存储(COS):https://cloud.tencent.com/product/cos
  • 区块链服务(BCS):https://cloud.tencent.com/product/bcs
  • 腾讯云直播(CSS):https://cloud.tencent.com/product/css
  • 腾讯云音视频处理(MPS):https://cloud.tencent.com/product/mps
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

【Android 异步操作】Handler 机制 ( MessageQueue 消息队列的阻塞机制 | Java 层机制 | native 层阻塞机制 | native 层解除阻塞机制 )

wait 方法阻塞 , 直到消息入队 , 链表中有了元素 , 会调用 notify 解除该阻塞 ; 在实际的 Android 中的 消息队列 MessageQueue 的同步机制 是在 native...层实现 的 ; 在创建 消息队列 MessageQueue , 调用了 nativeInit() 方法 , 销毁 MessageQueue 时调用 nativeDestroy 方法 ; 如果调用...next 获取下一个消息 , 如果当前消息队列 MessageQueue 中没有消息 , 此时需要阻塞 , 调用 nativePollOnce 即可实现在 native 阻塞线程 ; // 初始化...(ptr, nextPollTimeoutMillis); } } 二、MessageQueue 的 native 层阻塞机制 ---- 线程阻塞方法 private native...---- 在 MessageQueue 消息队列的 Java 层 , 将 Message 消息插入到链表表头后 , 调用nativeWake 方法 , 唤醒了线程 , 即解除了阻塞 ; public

1.3K00

深入理解 Android 消息机制原理

最后调用epoll_ctl监控mWakeEventFd文件描述符的Epoll事件,即mWakeEventFd中有内容可读,就唤醒当前正在等待的线程.。...什么是Epoll模型?我先简单介绍一下。 Epoll(必看!!!) 为什么要引入? 在Looper.loop的时候提到了,android不会简单粗暴地真的执行啥都没干的死循环。...Epoll干的事就是: 如果你的queue中没有消息可执行了,好了你可以歇着了,等有消息的我再告诉你。这个queue.next就是“阻塞”(休眠)在这里。...其实native层主要负责的是消息的调度,比如说何时阻塞、何时唤醒线程,避免CPU浪费。...native发送 发送在native比较简单,handler发送消息后,会到MessageQueue的enqueueMessage,此时在线程阻塞的情况下,会调用nativeWake来唤起线程

2K41
  • Android中的Handler机制中的问题总结

    获取,来保证每个线程间只会有一个Looper对象 有Message要进入Looper,从ThreadLocal中获取Looper Loop的实现原理 Looper通过Linux的epoll来实现阻塞唤醒的...// 那么就会唤醒执行任务, 不直接执行任务的原因是这个函数可能会在子线程调用 msg.next = p;..., MessageQueue.next()会走到以下逻辑开始处理Idlehandler // 消息链表中没有需要处理的消息 if (pendingIdleHandlerCount...例如, 当前主线程中有A->B->C->D->E五个消息, 而E需要高优执行的时候(其实就是Android中的VSync重绘任务), 其中A为SyncBarrier, 则轮到A执行的时候, MessageQueue...需要插入任务, 使用Handler.getLooper().getMessageQueue().postSyncBarrier()插入栅栏, 在要插入的消息中设置Message.setAsynchronous

    1.1K20

    看完这篇,别再说你不了解 Handler 消息机制了

    的逻辑会根据 Message 的执行时间 Message.when 按大小排序,队头 when 小,队尾 when 大,然后判断线程是否休眠,如果是,则调用 native 方法 nativeWake 唤醒线程...Runnable B、消息进队,判断现在 A 时间还没到、正在阻塞,把 B 插入消息队列的头部(A的前面),然后调用nativeWake()方法唤醒线程;MessageQueue.next()方法被唤醒后...所以这也是为什么在主线程中可以直接实例化 Handler 的原因。...当前线程阻塞在 loop() 里面的 mQueue.next() 方法中,MessageQueue 的 next() 方法中也有一个死循环,没有更多消息的时候,会阻塞在这个循环里面。...这里不是简单的死循环,所以阻塞不会消耗太大的资源,无消息的时候线程会进入休眠状态,CPU 资源会被释放给其他线程使用;有新消息的时候,线程会被唤醒,继续执行 loopMessage next() {

    64921

    「细品源码」 Android 系统的血液:Handler

    如何判断这个位置?依然是通过消息被执行的时间。 通过遍历整个队列,队列中的某个消息的执行时间比当前消息晚,将消息插到这个消息的前面。...最后是一个空闲监听处理,作用是队列中没有需要执行的消息,说明线程进入空闲状态,这时候可以去执行一些其他的任务。...唤醒线程 消息队列为空的时候,Loop 会进入无限阻塞挂起,如果这时候用户发送了一个消息,这时候如何唤醒线程?... timeoutMillis == 0 或者超时唤醒,会跳转到 Done ,结束调用,返回。...Loop.looper() 死循环为什么不会阻塞线程 经过上面的分析,App 的主线程中通过 Loop.looper() 开启了消息“死循环”,那为什么 App 依然可以正常运转,没有阻塞到主线程

    99860

    Handler:Android 消息机制,我有必要再讲一次!

    线程为啥一定要调用 Looper.prepare() 和 Looper.loop()? Handler 的简单使用 相信应该没有人不会使用 Handler 吧?...这是一个 Native 方法,实际作用是通过 Native 层的 MessageQueue 阻塞当前调用线程 nextPollTimeoutMillis 毫秒的时间。...置为 -1,此时满足小于 0 的条件,会被一直阻塞,直到其他地方调用另外一个 Native 方法 nativeWake(long) 进行唤醒。...ThreadLocal 是用来存储指定线程的数据的,某些数据的作用域是该指定线程并且该数据需要贯穿该线程的所有执行过程就可以使用 ThreadnLocal 存储数据,线程使用 ThreadnLocal...可能你会疑问,我在主线程使用的时候,没有要求 Looper.prepare() 呀。

    38510

    Looper,MassageQuene,Handler

    所以一个线程一个Looper一个MessageQuene多个Handler 主线程和子线程使用区别 主线程为什么不用进行Looper.prepare()和Looper.loop()方法的调用就可以使用Hnadler...而其他子线程需要调用上述两个方法才能使用Handler。...所以主线程也要调用只不过ActivityThread帮你做了 大概流程 Looper中for(;;)死循环调用MessageQuene的next()方法(该方法也为for(;;)死循环)取出最新消息。...MessageQuene中取消息时会判断target是否为空(同步屏障消息),如果为空去取下一个消息:如果为同步消息不发送,异步消息才进行发送 主线程如何在for(;;)情况实现不阻塞线程 MessageQuene...中没有消息会调用nativePollOnce进行阻塞用于标识当前无消息,有消息进入队列时会调用nativeWake进行唤醒队列。

    40720

    深入解析Android中Handler消息机制

    Handler的简单使用 为什么系统不允许子线程更新UI 因为的UI控件不是线程安全的。 如果在多线程中并发访问可能会导致UI控件处于不可预期的状态,那为什么不对UI控件的访问加上上锁机制?...通过ThreadLocal.set()将这个新创建的对象的引用保存到各线程的自己的一个map中,每个线程都有这样一个map,执行ThreadLocal.get(),各线程从自己的map中取出放进去的对象...Looper的,但是为什么在主线程没有创建的Looper就可以使用Handler?...主线程,也就是ActivityThread,线程被创建的时候,会调用Looper内的prepareMainLooper方法,创建Looper,该方法是专门给主线程创建Looper用的。...MessageQueue没有消息,next方法会一直阻塞在那里,因为MessageQueue的next方法阻塞了,就导致Looper的loop方法也一直在阻塞了。

    52230

    深入理解Android消息机制

    为什么线程不卡? 分析完基本的消息机制,既然 Looper 的 looper 方法是一个for(;;;)循环,那么新的问题提出来了。为什么Android会在主线程使用死循环?...执行死循环的时候为什么线程阻塞没有导致CPU占用的暴增?...继续分析在源码中我们没有分析的部分: 消息队列构造的时候是否调用了jni部分 nativeWake、nativePollOnce这些方法的作用是什么 先查看MQ的构造方法: MessageQueue(boolean...的回调机制,迅速激活这个文件描述符,进程调用epoll_wait()便得到通知 关于epoll和select,可以举一个例子来表达意思。...Java层通过调用 pollonce 来达到调用底层epoll 让死循环进入阻塞休眠的状态,以避免浪费CPU, 所以这也解释了为什么Android Looper的死循环为什么不会让主线程CPU占用率飙升

    53620

    面试官还问Handler?那我要给你讲个故事

    如果消息为异步消息则通过Message.when长短插入到队列对应位置,不唤醒Looper线程。 接下来该面试官问了 经常有人问为什么线程的Looper阻塞不会导致ANR?...首先我们得知道ANR是主线程5秒内没有响应。 什么叫5秒没有响应?Android系统中所有的操作均通过Handler添加事件到事件队列,Looper循环去队列去取事件进行执行。...那子线程怎么创建Handler?只需在new Handler()之前调用下Looper.prepare()即可。 2. 为什么线程可以直接new Handler?...子线程直接new Handler会报错,主线程为什么就不会报错?主线程我也没有调用Looper.prepare()啊?那么我们还得看下源码了。...垃圾回收机制:Java采用根搜索算法,GC Roots不可达,并且对象finalize没有自救的情况下,才会回收。

    43660

    Android面试必备知识点:Android中Handler八大问题汇总

    首先给出结论,Looper不会一直消耗系统资源,Looper的MessageQueue中没有消息,或者定时消息没到执行时间,当前持有Looper的线程就会进入阻塞状态。...再看看下面这个方法:nativePollOnce(ptr, nextPollTimeoutMillis);nextPollingTimeOutMillis=-1,这个native方法会阻塞当前线程,...线程阻塞后,等下次有消息入队才会重新进入可运行状态,所以Looper并不会一直死循环消耗运行内存,对队列中的颜色消息还没到时间也会阻塞当前线程,但是会有一个阻塞时间也就是nextPollingTimeOutMillis...消息队列中没有消息的时候looper肯定是被消息入队唤醒的。...; } 上面可以看到消息入队之后会有一个 if (needWake) { nativeWake(mPtr); } 方法,调用这个方法就可以唤醒线程

    1.2K20

    面试问关于Handler的这些问题你知道吗?

    Looper.loop() 为什么不会阻塞APP? 可以监测到 MessageQueue 中无数据的情况吗?可以的话,通过什么方式?...---- Handler 相关问题的解答 以下代码中省略了无关代码 Q :在线程中可以直接调用 Handler 无参的构造方法吗?在主线程和子线程中有没有区别?...A:因为在没有可用消息的时候会休眠,然后 MessageQueue 有可用消息之后(新增的 when<=0 的消息或者到达指定when)会通过 epoll机制 唤醒。... Message 得不到处理,被 Handler 持有的外部对象会一直处于内存泄漏状态。 ---- Q :在子线程中如何获取当前线程的 Looper?...A:调用静态方式 Looper.myLooper(),在子线程没有调用 Looper.prepare(),返回null. public static @Nullable Looper myLooper

    27460

    Android 一起来看看面试必问的消息机制

    Handler 的主要功能是将任务切换到某个指定的线程中去执行,那么 Android 为什么要提供这个功能?...这是因为 Android 规定访问 UI 只能在主线程中进行,如果在子线程中访问 UI,那么程序就会抛出异常。 那为什么 Android 不允许子线程中访问 UI ?...这是因为 Android 的 UI 控件并不是线程安全的,如果在多线程中并发访问可能会导致 UI 控件处于不可预期的状态,那还有一个问题,为什么系统不对 UI 控件的访问加上锁机制?...我们知道,Handler 的工作需要 Looper,没有 Looper 的线程就会报错,那么如何为一个线程创建 Looper ?...的 quit() 被调用时,Looper 就会调用 MessageQueue 的 quit() 或者 quitSafely() 方法来通知消息队列退出,当前消息队列被标记为退出状态,它的 next

    33430

    深入Handler、Looper、MessageQueue

    调用nativePollOnce(ptr, nextPollTimeoutMillis)进行阻塞,这是一个本地方法,会调用底层C++代码,C++代码最终会通过Linux的epoll监听文件描述符的写入事件来实现延迟...二、Looper.loop是一个死循环,拿不到需要处理的Message就会阻塞,那在UI线程为什么不会导致ANR?...ActivityThread没有继承Thread,他不是主线程。个人猜测当前进程就是主线程。 1.为什么阻塞 一个线程,如果执行完成,该线程会消亡。...如果当前Looper不阻塞,执行完成,那app直接嗝屁。 2.阻塞为什么还能跳转页面等操作 这个问题是2个问题。第一个是如何执行页面跳转等操作,第二个是阻塞为什么还能操作页面。...第二个,阻塞后还能操作,跳转页面,还能调用各种声明周期。我们可以看到ActivityThread定义了内部类Handler,他和Looper都是在同一线程即主线程

    36620

    Android Handler机制 – MessageQueue如何处理消息

    而next方法显然就是用于获取下一条消息的,其中主要通过nativePollOnce从native层的MessageQueue中获取,并且该方法会阻塞线程,如果获取不到消息(比如消息队列中是空的),就一直阻塞...本次调查的结论 nativePollOnce 确实没有导致ANR,也不会过度消耗cpu cycle,它只是说明当前handlerthread中没有需要处理的message,线程在等待下一条message...,其值为 false ,不会crash,只是 listFiles() 接口返回的那个有问题的文件名不一定能准确识别出来,我想Google做这种机制的目的在于,开发通过crash提示开发者有非utf...利用epoll的机制,可以做到管道没有消息线程睡眠在读端的fd上,其他线程往管道写数据,本线程便会被唤醒以进行消息处理。...loop方法里会调用MessageQueue的next方法。next方法会堵塞线程直到有消息到来为止。 next方法通过调用nativePollOnce方法来监听事件。

    71420

    Android 进阶14:源码解读 Android 消息机制( Message MessageQueue Handler Looper)

    如果有阻塞没有消息了或者只有 Delay 的消息),会把 mBlocked这个变量标记为 true,在下一个 Message 进队时会判断这个message 的位置,如果在队首就会调用 nativeWake...public static interface IdleHandler { //消息队列没有消息时会回调这个方法,阻塞等待有消息进入 //返回 true 的话表示唤醒阻塞线程,false...表示移除 //如果消息队列中有消息等待在将来执行,也会调用这个方法 boolean queueIdle(); } 根据源码和注释我们可以知道 IdleHandler 是一个线程阻塞回调的接口...mLogging; private long mTraceTag; 线程中默认没有 Looper,我们需要调用 Looper.prepare() 方法为当前线程创建一个 Looper,然后就可以调用 loop...这时消息已经在创建 Handler 的线程了 这个“线程切换” 是怎么实现的

    1.4K90

    【面试专题】2021年字节、阿里、网易等 Handler 面试题集合,Android高级开发必备!

    Looper死循环为什么不会导致应用卡死?...Handler是native层的阻塞、唤醒(nativePollOnce、nativeWake)机制,应用卡死那是ANR(这边可以展开说一下 ANR),有条件的可以说一下 Linux 底层的消息机制(这个绝对是加分项...这边可能会被问,sThreadLocal为什么是static的?这边答案我不太确定,我面试的时候是答的只需要装载一次,减少对象创建开销;线程内所有操作共享。有知道为什么的大佬可以评论区教教大家。...,可能会了立即返回(立即执行); 等于-1,无消息,会一直堵塞; 阻塞内部就是通过native函数nativePollOnce、nativeWake来实现的,这边可以展开说,说清楚了你就是P7大佬了...线程将要进入堵塞,以等待更多消息,会回 调这个接口。简单点说:MessageQueue中无可处理的Message回调。

    1.7K21
    领券