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

如何使用Threads实现两个不同任务打印1-10?线程重复执行问题求助

嘿,我明白你现在的困扰啦——查了一堆线程相关的问题,看着答案好像懂了,但一用到自己的代码里就出问题,两个线程居然跑成了一样的操作,输出全是重复的数字,太闹心了😅

先帮你拆解下核心问题:你想要两个线程配合输出1 2 3 4 5 6 7 8 9 10,但现在出现重复输出,本质是线程共享了同一个可变状态,又没做好任务划分或同步控制。结合你贴的代码片段,大概率是两个线程共用了同一个PrintRunnable实例,抢着修改同一个num变量,导致输出重复。

下面给你两种针对性的解决方案,按需选就行:

方案1:给每个线程分配独立的任务区间(简单直接)

这种方法不用复杂同步,直接让每个线程负责一段数字的输出,互不干扰。

先修改你的PrintRunnable类,让它接收起始和结束数字:

package midtermpractice;

public class PrintNums {
    public static class PrintRunnable implements Runnable {
        private int start;
        private int end;

        // 构造方法传入任务的起始和结束数字
        public PrintRunnable(int start, int end) {
            this.start = start;
            this.end = end;
        }

        @Override
        public void run() {
            // 只输出自己负责的区间
            for (int i = start; i <= end; i++) {
                System.out.print(i + " ");
            }
        }
    }

    public static void main(String[] args) {
        // 第一个线程输出1-5,第二个输出6-10
        new Thread(new PrintRunnable(1, 5)).start();
        new Thread(new PrintRunnable(6, 10)).start();
    }
}

运行后就能得到你要的输出(注:线程启动顺序不固定,偶尔可能先输出6-10再1-5,但数字绝对不会重复)。

方案2:用同步机制实现严格顺序输出(如果需要1-10依次打印)

如果你要求两个线程必须交替输出1、2、3...10,那就要用锁和等待/唤醒机制来控制线程的执行顺序:

package midtermpractice;

public class PrintNums {
    public static class PrintRunnable implements Runnable {
        // 共享的当前要输出的数字
        private static int currentNum = 1;
        // 全局锁,用来同步线程
        private static final Object lock = new Object();
        // 线程标识:1负责奇数,2负责偶数
        private final int threadId;

        public PrintRunnable(int threadId) {
            this.threadId = threadId;
        }

        @Override
        public void run() {
            while (currentNum <= 10) {
                synchronized (lock) {
                    // 判断当前是否轮到自己输出:奇数给线程1,偶数给线程2
                    while ((currentNum % 2 == 1 && threadId != 1) || (currentNum % 2 == 0 && threadId != 2)) {
                        try {
                            lock.wait(); // 没轮到自己就等待,释放锁
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                            return;
                        }
                    }
                    // 确认还在输出范围内,打印并更新数字
                    if (currentNum <= 10) {
                        System.out.print(currentNum + " ");
                        currentNum++;
                        lock.notifyAll(); // 唤醒另一个线程,让它继续
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        new Thread(new PrintRunnable(1)).start();
        new Thread(new PrintRunnable(2)).start();
    }
}

这个版本会严格按照1、2、3...10的顺序输出,不会有任何重复或顺序混乱。

总结下:你之前的问题就是因为多个线程共享了同一个num变量,又没做任务隔离或同步,导致线程互相干扰。只要给每个线程明确独立的任务,或者用同步机制控制执行顺序,就能解决啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 10:09:24