如何确保10个对应打印数字的线程按预定顺序执行输出1至10?
如何让10个线程按顺序打印1到10?
这个问题的核心是要强制线程按指定顺序执行——默认情况下操作系统会随机调度线程,直接启动10个线程的话,输出顺序大概率是混乱的。下面我会用几种主流编程语言给出可行的实现方案,每个方案都配有代码示例和原理说明:
方法1:按顺序调用线程的join()(最简单的串行式实现)
这种方式思路非常直接:主线程逐个创建并启动线程,每启动一个就立刻调用join(),等待这个线程完成打印后,再创建并启动下一个线程。本质上是让线程串行执行,虽然没用到并发的优势,但完全满足需求。
Python 示例
import threading def print_num(num): print(num, end=" ") if __name__ == "__main__": threads = [] for i in range(1, 11): t = threading.Thread(target=print_num, args=(i,)) threads.append(t) t.start() t.join() # 等待当前线程完成后再继续下一个
C++ 示例
#include <iostream> #include <thread> void print_num(int num) { std::cout << num << " "; } int main() { for (int i = 1; i <= 10; ++i) { std::thread t(print_num, i); t.join(); // 等待当前线程执行完毕 } return 0; }
Java 示例
public class OrderedThreads { public static void main(String[] args) throws InterruptedException { for (int i = 1; i <= 10; ++i) { Thread t = new Thread(() -> System.out.print(i + " ")); t.start(); t.join(); } } }
方法2:用条件变量实现真正的并发等待(适合需要并发场景的情况)
如果希望线程都先启动,再按顺序执行打印操作(真正的并发等待),可以用共享状态+条件变量的方式:维护一个全局的“当前允许打印的数字”,每个线程启动后先等待,直到这个数字等于自己要打印的编号,再执行打印,然后更新数字并通知下一个线程。
Python 示例(用threading.Condition)
import threading current_num = 1 cond = threading.Condition() def print_num(num): global current_num with cond: # 等待直到当前允许打印的数字是自己的编号 while current_num != num: cond.wait() print(num, end=" ") current_num += 1 cond.notify_all() # 通知所有等待的线程 if __name__ == "__main__": threads = [] for i in range(1, 11): t = threading.Thread(target=print_num, args=(i,)) threads.append(t) t.start() # 等待所有线程完成 for t in threads: t.join()
C++ 示例(用std::condition_variable)
#include <iostream> #include <thread> #include <condition_variable> #include <mutex> std::mutex mtx; std::condition_variable cv; int current_num = 1; void print_num(int num) { std::unique_lock<std::mutex> lock(mtx); // 等待直到当前数字匹配 while (current_num != num) { cv.wait(lock); } std::cout << num << " "; current_num++; cv.notify_all(); // 唤醒所有等待的线程 } int main() { std::thread threads[10]; for (int i = 0; i < 10; ++i) { threads[i] = std::thread(print_num, i+1); } for (auto& t : threads) { t.join(); } return 0; }
Java 示例(用synchronized和wait()/notifyAll())
public class OrderedThreads { private static int currentNum = 1; private static final Object lock = new Object(); public static void main(String[] args) { for (int i = 1; i <= 10; ++i) { new Thread(new PrintTask(i)).start(); } } static class PrintTask implements Runnable { private final int num; PrintTask(int num) { this.num = num; } @Override public void run() { synchronized (lock) { try { while (currentNum != num) { lock.wait(); } System.out.print(num + " "); currentNum++; lock.notifyAll(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } } }
方法3:用CountDownLatch(Java专属的优雅方案)
Java的CountDownLatch可以用来让线程等待前一个线程完成。我们可以为每个线程设置一个依赖的latch,只有前一个线程完成后,当前线程的latch才会被触发。
import java.util.concurrent.CountDownLatch; public class OrderedThreads { public static void main(String[] args) throws InterruptedException { CountDownLatch previousLatch = new CountDownLatch(1); // 第一个线程的latch初始为1,直接执行 for (int i = 1; i <= 10; ++i) { CountDownLatch currentLatch = new CountDownLatch(1); new Thread(new PrintTask(i, previousLatch, currentLatch)).start(); previousLatch = currentLatch; } // 触发第一个线程开始执行 previousLatch.countDown(); } static class PrintTask implements Runnable { private final int num; private final CountDownLatch waitLatch; private final CountDownLatch signalLatch; PrintTask(int num, CountDownLatch waitLatch, CountDownLatch signalLatch) { this.num = num; this.waitLatch = waitLatch; this.signalLatch = signalLatch; } @Override public void run() { try { waitLatch.await(); // 等待前一个线程的信号 System.out.print(num + " "); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { signalLatch.countDown(); // 通知下一个线程可以执行了 } } } }
以上几种方案都能保证输出严格按照1 2 3 ... 10的顺序执行,你可以根据自己使用的编程语言和实际场景选择合适的方案。
内容的提问来源于stack exchange,提问作者Subhajit Kundu
相关产品推荐
相关产品推荐

