求助:多线程按顺序打印1-10奇偶数字的同步实现问题
问题分析
你的代码核心问题有两个:
- 两个线程持有不同的Counter实例,
synchronized(this)锁定的是各自的对象,完全起不到跨线程的同步作用,两个线程会各自独立跑完自己的循环,输出顺序必然混乱。 - 缺少线程间的通信机制,无法让奇数线程和偶数线程交替执行,自然无法实现1到10的有序输出。
修复方案
要实现有序交替打印,需要让两个线程共享同一个锁对象,并且通过wait()和notifyAll()实现线程间的唤醒与等待,确保每次只有一个线程执行打印操作,完成后立即切换到另一个线程。
以下是修复后的完整代码:
public class Counter implements Runnable { // 所有线程共享的锁对象 private static final Object lock = new Object(); private int num; private String name; // 记录当前需要打印的数字,保证输出顺序 private static int current = 1; public Counter(int i, String name) { this.num = i; this.name = name; } @Override public void run() { while (current <= 10) { synchronized (lock) { // 判断是否轮到当前线程打印:奇数线程处理奇数,偶数线程处理偶数 while ((current % 2) != num) { try { // 不是自己的轮次,释放锁并等待 lock.wait(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); return; } } // 打印当前数字 System.out.println(name + "-->" + current); current++; // 唤醒等待的另一个线程 lock.notifyAll(); } } } public static void main(String[] args) { Thread t1 = new Thread(new Counter(1, " ODD")); Thread t2 = new Thread(new Counter(0, " EVEN")); t1.start(); t2.start(); } }
关键逻辑说明
- 共享锁对象:用
private static final Object lock作为所有线程的同步锁,确保两个线程竞争同一把锁,实现真正的同步控制。 - current变量:静态变量,记录当前需要打印的数字,从1开始递增到10,保证输出顺序严格从1到10。
- wait()/notifyAll():每个线程进入同步块后,先判断是否轮到自己打印,如果不是则调用
wait()释放锁并进入等待状态;打印完成后递增current,再调用notifyAll()唤醒另一个线程,实现交替执行。 - 中断处理:捕获
InterruptedException后中断当前线程,避免线程因异常挂起无法正常退出。
运行这段代码后,就能得到ODD-->1、EVEN-->2、ODD-->3……EVEN-->10的有序输出。
内容的提问来源于stack exchange,提问作者Vidhusan Surenthiran
相关产品推荐
相关产品推荐

