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

Java两个Runnable线程轮流打印大小写字母代码问题求助

核心问题排查
  • 开关变量未共享:你创建了两个独立的ABCPrinter实例,每个实例持有独立的bool_Switch变量,线程修改的是自己实例的开关,无法起到轮流控制的作用
  • 锁对象不统一:run方法的synchronized修饰符锁的是当前Runnable实例,两个线程锁的是不同对象,wait()和notifyAll()无法跨线程生效,最终两个线程都会进入永久等待
  • 小写打印逻辑错误:小写分支调用了Character.toUpperCase(),输出的还是大写字母,不符合需求
  • 休眠时间不合理:多处设置10秒休眠,调试成本极高
可直接运行的修复后代码

ABCPrinter类

public class ABCPrinter implements Runnable {
    // 静态开关加volatile修饰,保证多线程可见性,所有实例共享
    private static volatile boolean printUpperTurn = true;
    private final boolean isUpperPrinter;

    public ABCPrinter(boolean isUpperPrinter) {
        this.isUpperPrinter = isUpperPrinter;
    }

    @Override
    public void run() {
        for (char c = 'a'; c <= 'z'; c++) {
            // 锁类全局唯一对象,保证两个线程用同一把锁
            synchronized (ABCPrinter.class) {
                // 未轮到当前线程时进入等待
                while ((isUpperPrinter && !printUpperTurn) || (!isUpperPrinter && printUpperTurn)) {
                    try {
                        ABCPrinter.class.wait();
                    } catch (InterruptedException e) {
                        System.out.println("线程中断:" + e.getMessage());
                    }
                }
                // 按需求打印大小写
                if (isUpperPrinter) {
                    System.out.println(Character.toUpperCase(c));
                } else {
                    System.out.println(Character.toLowerCase(c));
                }
                // 切换打印轮次
                printUpperTurn = !printUpperTurn;
                // 通知等待的另一个线程
                ABCPrinter.class.notifyAll();
            }
        }
    }
}

Main启动类

public class Main2 {
    public static void main(String[] args) {
        ABCPrinter upperPrinter = new ABCPrinter(true);
        ABCPrinter lowerPrinter = new ABCPrinter(false);
        
        Thread upperThread = new Thread(upperPrinter);
        Thread lowerThread = new Thread(lowerPrinter);

        upperThread.start();
        lowerThread.start();
    }
}

运行后将按A a B b ... Z z的顺序轮流输出,完全符合需求。

可选优化建议
  • 移除调试日志:原有代码里的流程状态打印可以在功能验证完成后删除,减少冗余输出
  • 代码复用:如果需要保留调试日志,可以把重复的打印、休眠逻辑提取为公共方法,避免大写、小写分支重复写相同代码
  • 异常处理优化:精准捕获InterruptedException而非宽泛的Exception,方便定位异常场景
  • 休眠调整:如果需要观察打印节奏,可以在同步块外添加短时间休眠,不要放在同步块内占用锁资源

内容的提问来源于stack exchange,提问作者TheWerefox

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 17:36:04