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

Java多线程实现数独有效性校验时非确定性输出问题咨询

问题原因

  1. 逻辑设计缺陷
    你当前的SudokuTest类中,只有setGrid()方法在执行完成后会调用allChecked()判断三类校验是否全部完成,setRow()、setCol()方法完成后都没有触发该判断。
    三个校验线程的执行顺序是完全随机的:如果Grid线程最先完成校验,此时行、列校验还未结束,allChecked()判断结果为false;后续行、列校验完成后,因为对应的set方法不会调用allChecked(),永远不会触发Main.success()执行,自然就不会打印"win"。
  2. 线程安全问题
    SudokuTest中所有的boolean成员变量没有做任何同步处理,也没有加volatile关键字修饰。在Java内存模型中,线程对共享变量的修改会先存到自己的工作内存,不会立刻同步到主内存,其他线程很可能读取到旧的变量值。就算逻辑上三类校验都已完成,也可能因为可见性问题导致allChecked()判断为false。

修复方案

  1. 补全逻辑:在setRow()、setCol()方法的最后都添加allChecked()调用,保证不管哪类线程最后完成校验,都能触发全量完成判断。
  2. 保证线程安全:给SudokuTest中所有操作共享变量的方法加synchronized关键字,或者给所有boolean成员变量加volatile修饰,保证变量修改的跨线程可见性,避免竞态条件。

修改后的SudokuTest参考代码

public class SudokuTest {
    public volatile boolean _rowBad;
    public volatile boolean _colBad;
    public volatile boolean _gridBad;
    public volatile boolean _rowChecked;
    public volatile boolean _colChecked;
    public volatile boolean _gridChecked;
    public SudokuTest(){

    }
    public synchronized void setRow(boolean b) {
        _rowBad = b;
        _rowChecked = true;
        if (b) {
            Main.end();
        }
        allChecked();
    }
    public synchronized void setCol(boolean b) {
        _colBad = b;
        _colChecked = true;
        if (b) {
            Main.end();
        }
        allChecked();
    }
    public synchronized void setGrid(boolean b) {
        _gridBad = b;
        _gridChecked = true;
        if (b) {
            Main.end();
        }
        allChecked();
    }
    public synchronized void allChecked() {
        if (_gridChecked && _colChecked && _rowChecked) {
            Main.success();
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 01:36:09