Java多线程打印奇偶数字问题:输出重复如何解决?
解决Java多线程顺序打印奇偶数字重复的问题
兄弟,你的问题根源在于两个线程各自持有独立的ThreadImplementation1实例,状态完全割裂,而且没有任何同步机制来协调打印顺序,自然会出现重复打印的情况。咱们一步步来解决:
问题分析
你创建两个Thread对象时,分别new了ThreadImplementation1,这意味着每个线程都有自己的isOdd变量,它们之间完全不知道对方的状态,各自跑各自的,打印数字时肯定会撞车,出现重复。
修复方案
要实现顺序打印奇偶,核心是让两个线程共享同一个状态(当前要打印的数字、该打印奇数还是偶数),并且用同步机制来协调线程的执行顺序。
步骤1:共享Runnable实例
让两个线程共用同一个ThreadImplementation1对象,这样它们操作的是同一套状态变量:
public class ThreadBasic1 { public static void main(String[] args) { // 只创建一个Runnable实例,两个线程共用它 ThreadImplementation1 sharedRunnable = new ThreadImplementation1(); Thread t1 = new Thread(sharedRunnable); Thread t2 = new Thread(sharedRunnable); t1.start(); t2.start(); } }
步骤2:修改Runnable类,加入同步与线程通信
在ThreadImplementation1中加入共享的数字变量,并用synchronized、wait()、notifyAll()来协调线程:
public class ThreadImplementation1 implements Runnable { // 共享的当前打印数字,初始从1开始 private int currentNum = 1; // 假设打印到10,你可以按需修改这个值 private final int MAX_NUM = 10; // 标记当前是否应该打印奇数 private boolean shouldPrintOdd = true; @Override public void run() { while (currentNum <= MAX_NUM) { // 同步块保证同一时间只有一个线程操作共享变量 synchronized (this) { // 用while循环判断,防止虚假唤醒 while ((shouldPrintOdd && currentNum % 2 == 0) || (!shouldPrintOdd && currentNum % 2 != 0)) { try { // 不满足打印条件,释放锁并等待 wait(); } catch (InterruptedException e) { // 处理中断,直接结束线程 Thread.currentThread().interrupt(); return; } } // 打印当前数字 System.out.println(Thread.currentThread().getName() + " 打印:" + currentNum); // 数字自增 currentNum++; // 切换奇偶标记 shouldPrintOdd = !shouldPrintOdd; // 唤醒所有等待的线程,让下一个符合条件的线程执行 notifyAll(); } } } }
为什么这样能解决问题?
- 共享状态:两个线程操作同一个
currentNum和shouldPrintOdd,状态完全统一,不会各自为政。 - 同步块:确保同一时间只有一个线程能修改共享变量,避免线程安全问题。
- wait/notify机制:让不符合打印条件的线程暂时等待,打印完成后主动唤醒其他线程,完美实现奇偶交替打印的顺序。
- while循环判断:用while而不是if,是为了防止线程被虚假唤醒后直接执行,必须再次检查条件是否满足。
内容的提问来源于stack exchange,提问作者Ashwani ojha
相关产品推荐
相关产品推荐

