多线程未并发执行求助:Log输出未交替显示(附代码)
多线程日志未交替输出的原因及修复方案
你的问题其实很典型——看起来是创建了两个线程,但实际上所有的日志打印逻辑都跑到UI线程里串行执行了,这才导致先打完所有bb日志再打aa的。
问题根源分析
你在每个自定义Thread的run()方法里,立刻调用了runOnUiThread(),把整个1000次的循环任务都丢给了UI线程。而Android的UI线程是单线程模型,消息队列里的任务会按顺序挨个执行:要么先处理完Thread b提交的循环,再处理Thread a的;要么反过来,总之不可能出现交替输出的情况。
而且要注意:Log类的打印方法根本不需要在UI线程执行,完全可以直接在子线程里调用。
修复方案
把日志循环直接放到子线程的run()方法中,去掉不必要的runOnUiThread()调用,让两个线程真正并行执行:
Thread a = new Thread() { @Override public void run() { Log.i("Thread", "Thread A Running"); try { for(int x = 0 ; x < 1000 ; x++){ Log.w("aa", String.valueOf(x)); // 加个短暂休眠,让交替效果更明显(线程调度速度快,不加可能还是会有连续输出) Thread.sleep(1); } } catch (Exception e) { e.printStackTrace(); } } }; Thread b = new Thread() { @Override public void run() { Log.i("Thread", "Thread B Running"); try { for(int x = 0 ; x < 1000 ; x++){ Log.w("bb", String.valueOf(x)); Thread.sleep(1); } } catch (Exception e) { e.printStackTrace(); } } }; a.start(); b.start();
特殊场景适配(如果需要UI操作)
如果你的实际需求里,除了打日志还要做UI更新(比如修改TextView内容),那也不要把整个循环丢到UI线程,应该只把单次UI操作放到runOnUiThread()里,循环逻辑仍留在子线程:
Thread a = new Thread() { @Override public void run() { Log.i("Thread", "Thread A Running"); try { for(int x = 0 ; x < 1000 ; x++){ final int finalX = x; // 仅将单次UI相关操作提交到UI线程 runOnUiThread(new Runnable() { @Override public void run() { Log.w("aa", String.valueOf(finalX)); // 比如这里可以加UI更新:textViewA.setText(String.valueOf(finalX)); } }); Thread.sleep(1); } } catch (Exception e) { e.printStackTrace(); } } }; // Thread b的修改逻辑和Thread a一致,这里省略
关键知识点回顾
runOnUiThread()是把任务提交到UI线程的消息队列,UI线程会串行处理所有任务,不能用来实现并行。- 不需要UI交互的逻辑(比如日志打印、数据计算),直接放在子线程执行即可,没必要绕到UI线程。
- 线程调度由系统控制,短暂的
Thread.sleep()可以让交替输出的效果更直观,但不是必须的。
内容的提问来源于stack exchange,提问作者Taha Sami
相关产品推荐
相关产品推荐

