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
相关产品推荐
相关产品推荐

