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

Java双线程逆序打印字符串每字符两次 如何保证输出稳定正确

问题根源

你当前的代码存在两个核心问题,导致输出结果随机、不符合预期:

  • 循环变量i是每个线程运行run方法时的局部变量,两个线程会各自独立完成一遍完整的字符串逆序遍历打印,本质是各打一遍完整逆序串,根本无法实现「每个字符连续打印两次」的要求
  • 打印操作没有做任何并发同步控制,JVM调度线程的顺序是随机的,两个线程的打印指令会互相穿插,输出顺序自然无法固定。
修正后代码
public class Print implements Runnable {
    private String string;
    // 共享的当前打印索引,初始指向字符串最后一位
    private int currentIndex;
    // 共享的当前字符打印计数
    private int printCount;

    Print(String string) {
        this.string = string;
        this.currentIndex = string.length() - 1;
        this.printCount = 0;
    }

    @Override
    public void run() {
        while (currentIndex >= 0) {
            // 加锁保证同一时间只有一个线程执行打印逻辑
            synchronized (this) {
                // 二次校验索引合法性,避免并发下索引越界
                if (currentIndex < 0) {
                    break;
                }
                // 打印当前字符+连字符
                System.out.print(string.charAt(currentIndex) + "-");
                printCount++;
                // 当前字符打印满2次,移动到前一个字符,重置计数
                if (printCount == 2) {
                    currentIndex--;
                    printCount = 0;
                }
            }
        }
    }
}

public class Task1 {
    public static void main(String[] args) {
        Print r = new Print("NAME");
        Thread t1 = new Thread(r);
        Thread t2 = new Thread(r);
        t1.start();
        t2.start();
    }
}
实现逻辑说明
  • 将打印位置索引、单字符打印计数设为Runnable实例的共享变量,两个线程操作同一份状态数据,不会再出现各自遍历全串的问题
  • 用synchronized给打印逻辑块加实例锁,保证打印操作的原子性,彻底避免两个线程的输出内容穿插错乱
  • 锁内增加索引合法性二次判断,规避极端调度场景下的字符串索引越界异常
  • 严格控制索引移动时机:仅当当前字符完成两次打印后,才将索引前移一位并重置打印计数,保证输出顺序固定为逆序、每个字符连续打印两次,运行后始终输出E-E-M-M-A-A-N-N-符合要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 06:18:09