Java双线程按顺序打印1-10遇问题:打印1后线程均等待
双线程顺序打印1-10的问题修复方案
原代码核心问题
你创建了两个独立的Multithreading实例,每个实例持有自己的object锁对象。线程t1等待的是t1m的锁,线程t2等待的是t2m的锁——这导致线程1调用notifyAll()时,只能唤醒等待自身锁的线程(也就是自己),线程2完全接收不到唤醒信号,最终两个线程都陷入等待状态。
修正后的实现(参考多线程顺序打印思路)
以下是不使用嵌套内部类的修正代码,核心是让两个线程共享同一锁对象和状态变量:
public class Multithreading implements Runnable { private static int count = 1; private static volatile String currentTurn = "1"; private final Object lock; private final String threadId; // 构造函数传入共享锁和当前线程标识 public Multithreading(Object lock, String threadId) { this.lock = lock; this.threadId = threadId; } @Override public void run() { try { while (count <= 10) { synchronized (lock) { // 循环检查,避免虚假唤醒 while (!threadId.equals(currentTurn)) { lock.wait(); } // 再次判断count,防止最后一次循环时已超出范围 if (count > 10) { break; } System.out.println(threadId + " " + count); count++; // 切换下一个线程的轮次 currentTurn = threadId.equals("1") ? "2" : "1"; lock.notifyAll(); } } } catch (InterruptedException e) { Thread.currentThread().interrupt(); e.printStackTrace(); } } public static void main(String[] args) { Object sharedLock = new Object(); // 两个线程共享同一锁对象 Multithreading t1Task = new Multithreading(sharedLock, "1"); Multithreading t2Task = new Multithreading(sharedLock, "2"); new Thread(t1Task).start(); new Thread(t2Task).start(); } }
关键修改说明
- 共享锁对象:通过构造函数将同一个
Object实例传递给两个任务,确保线程间使用同一把锁进行同步。 - 循环条件检查:用
while替代原代码的if判断轮次,避免线程被虚假唤醒后直接执行打印逻辑。 - 状态变量可见性:
currentTurn用volatile修饰,保证线程间的状态可见性。 - 线程标识解耦:通过构造函数传入线程标识,不依赖
Thread.getName(),逻辑更清晰可控。
内容的提问来源于stack exchange,提问作者meme
相关产品推荐
相关产品推荐

