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

如何确保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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 06:46:17