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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:40:36