【问题标题】:Non-deterministic behavior with Java MultithreadingJava 多线程的非确定性行为
【发布时间】:2021-11-12 22:51:02
【问题描述】:

我编写了一个简单的程序,用于在 Java 中练习多线程。目标是测试数独解决方案是否有效:行、列或子网格中没有重复的数字。在这一点上,我不在乎条目必须来自 1-9。当数独解法无效时,程序运行良好。当数独解决方案有效时(在同一输入上),程序仅在某些时候有效。具体来说,“win”可能会被打印出来,也可能不会被打印出来。

我的程序通过创建 RowThread、ColumnThread 和 GridThread 来工作。他们每个人都分别检查解决方案是否具有有效的行、列和网格。当一个线程完成检查后,它会调用 SudokuTest 中适当的 setter 方法,如果解决方案无效,它将调用 Main 中的 end 方法。如果线程没有判断出解决方案无效,setter方法会记录行、列或网格已经被检查过,然后调用allChecked方法。 allChecked 检查是否已检查行、列和网格。如果是这样,那么解决方案是有效的,所以它调用 Main.success(),它应该打印“win”。这是我的主要课程:

public class Main{
    public static void end(){//called by SudokuTest when the solution is invalid
        System.out.println("fail");
        System.exit(0);
    }
    public static void success() {//called by SudokuTest when the solution is valid
        System.out.println("win");/*this line will not always print,
 but it is reached in the debugger when I set a breakpoint.*/
        System.exit(0);
    }

    public static void main(String[] args) {
        int[][] sudokuSolution = new int[9][9];
        int k = 0;
        for (int i = 0; i < 9; i++) { //loop fills up a 2d array with the numbers 0-80, a valid solution
            for (int j = 0; j < 9; j++) {
                sudokuSolution[i][j] = k;
                k++;
            }
        }
        //sudokuSolution[1][1] = 0;//Testing an invalid solution
        
        SudokuTest t = new SudokuTest();//
        Runnable r = new RowThread(sudokuSolution, t);
        Runnable c = new ColumnThread(sudokuSolution, t);
        Runnable g = new GridThread(sudokuSolution, t);
        new Thread(r).start();
        new Thread(c).start();
        new Thread(g).start();

    }
}

我的 RowThread 类:


public class RowThread implements Runnable {
    int[][] _sudoku;
    SudokuTest _t;
    public RowThread(int[][] sudoku, SudokuTest t) {
        _sudoku = sudoku;
        _t = t;
    }
    private void isFail() { //issue: how to get this info back to my Main function?
        for(int i = 0; i < _sudoku.length; i++) {
            for(int j = 0; j< _sudoku.length; j++) {
                for (int k = j+1; k< _sudoku.length; k++) {
                    if (_sudoku[i][j] == _sudoku[i][k]) {
                        _t.setRow(true);
                        return;
                    }
                }
            }
        }
        _t.setRow(false);
    }

    @Override
    public void run() {
        isFail();
    }
}

我的 ColumnThread 和 GridThread 类与 RowThread 相同,除了 isFail() 方法中的逻辑。 我的数独测试课:

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

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

【问题讨论】:

  • 你为什么只在setGrid上打电话给allChecked?如果最后没有调用它会发生什么?使用等待 latch 的主线程怎么样?只有当所有三个线程都调用成功时才会继续?
  • 我不敢相信我错过了。我的程序现在工作正常。非常感谢!
  • @PhillipFeldman 请张贴并接受对您自己的问题的回答,以显示解决方案,为后代着想。

标签: java multithreading undefined-behavior sudoku non-deterministic


【解决方案1】:

答案:正如 Maarten Bodewes 指出的那样,我的错误是没有在 setCol 和 setRow 中调用 allChecked。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-20
    • 1970-01-01
    • 2019-02-19
    相关资源
    最近更新 更多