如何使用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
相关产品推荐
相关产品推荐

