You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

强制调用runOnUiThread发布进度时回调全部滞后的问题咨询

问题根源

  • runOnUiThread属于异步投递接口,调用后仅会将onProgressUpdate任务插入主线程消息队列就直接返回,不会同步等待主线程执行该任务。
  • 你的10万次for循环执行速度极快,全程仅需几毫秒,在此期间主线程没有抢到CPU时间片执行队列中的任务,所有的### INNER ###会先被打印完毕,等后台线程跑完循环后,主线程才会批量执行队列中所有的进度更新任务,因此出现你看到的输出顺序。
  • 你调整synchronized块没有效果,是因为只要onProgressUpdate中没有对同一个this对象加锁,锁逻辑不会影响主线程任务的执行时机,自然解决不了顺序问题。

解决方法

方案1:模拟AsyncTask的常规进度更新效果

如果只需要视觉上的穿插输出,在每次投递进度任务后让后台线程短暂休眠,让出CPU时间片给主线程执行即可:

synchronized (this) {
    for (int i = 0; i < 100000; i++) {
        if (i % 100 == 0) {
           System.out.println("### INNER ### ");
           activity.runOnUiThread(this::onProgressUpdate);
           // 休眠10ms,给主线程留执行窗口
           try {
               Thread.sleep(10);
           } catch (InterruptedException e) {
               Thread.currentThread().interrupt();
           }
        }
    }
}

方案2:严格保证执行顺序

如果业务要求必须等本次进度更新执行完再继续后台任务,可以用CountDownLatch做同步等待:

synchronized (this) {
    for (int i = 0; i < 100000; i++) {
        if (i % 100 == 0) {
           System.out.println("### INNER ### ");
           CountDownLatch latch = new CountDownLatch(1);
           activity.runOnUiThread(() -> {
               onProgressUpdate();
               latch.countDown();
           });
           // 阻塞等待主线程执行完进度更新
           try {
               latch.await();
           } catch (InterruptedException e) {
               Thread.currentThread().interrupt();
           }
        }
    }
}

内容的提问来源于stack exchange,提问作者Luis A. Florit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 20:27:00