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

如何控制两个线程run方法的执行顺序?为何输出中running...不连续?

线程执行顺序相关问题解答

问题1:如何控制两个线程run方法的执行顺序?

默认情况下,Java线程采用抢占式调度,CPU会随机给就绪状态的线程分配时间片,所以线程执行顺序是不确定的。如果要严格控制两个线程run()方法的执行顺序,有几种实用方案:

  • 使用join()方法:这是最直接的同步方式,让一个线程等待另一个线程执行完毕后再继续运行。比如在你的代码里,想让t1的run()先执行完再启动t2的run(),可以修改主线程逻辑:

    t1.start();
    t1.join(); // 主线程暂停,等待t1执行完成
    t2.start();
    

    这样t2会在t1彻底执行结束后,才启动并执行自己的run()方法。

  • 使用CountDownLatch同步工具:适合更复杂的多线程同步场景。比如初始化一个计数为1的CountDownLatch,让t2在run()方法里等待这个latch,t1执行完后调用countDown(),t2就会立刻开始执行。

  • 使用单线程线程池:通过Executors.newSingleThreadExecutor()创建单线程池,把两个线程任务提交进去,线程池会严格按照提交顺序依次执行任务,自然就能控制顺序。


问题2:最后一个"running..."为何没有紧跟在第一个"running..."之后输出?

这是线程并发调度特性导致的正常现象,我们拆解下代码的执行流程就懂了:

  1. 主线程先创建t1、t2对象,打印它们的初始名称和t1的ID。
  2. 调用t1.start()和t2.start():这两个方法只是把线程从新建状态转为就绪状态,等着CPU分配时间片,并不是立刻执行run()方法。
  3. 主线程不会等子线程,会继续执行后续代码:修改t1的名称,打印After changing name of t1:Sonoo Jaiswal。
  4. CPU会在主线程和两个就绪的子线程之间随机分配时间片:可能主线程先跑完自己的打印逻辑,才轮到t2执行run();也可能子线程的执行被主线程打断,输出穿插在一起。

你看到的输出顺序就是典型的并发执行结果,因为没有任何同步机制保证两个子线程的run()会连续执行。比如实际执行时序可能是这样的:

主线程:打印t1/t2名称 → 打印t1的ID → 启动t1 → 启动t2 → 修改t1名称 → 打印修改后的名称
子线程t1:被CPU调度 → 打印"running..."
子线程t2:主线程完成打印后才被CPU调度 → 打印"running..."

这就导致两个"running..."之间插入了主线程的输出内容。


内容的提问来源于stack exchange,提问作者Math_Zombie

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:38:36