简体   繁体   English

Java 多线程的非确定性行为

[英]Non-deterministic behavior with Java Multithreading

I wrote a simple program that I am using to practice multithreading in Java.我编写了一个简单的程序,用于在 Java 中练习多线程。 The goal is to test whether or not a Sudoku solution is valid: No repeating numbers in rows, columns, or sub-grids.目标是测试数独解决方案是否有效:行、列或子网格中没有重复的数字。 At this point I don't care that the entries must be from 1-9.在这一点上,我不在乎条目必须是 1-9。 The program works fine when the Sudoku solution is invalid.当数独解决方案无效时,程序运行良好。 When the Sudoku solution is valid (on the same input), the program works only sometimes.当数独解决方案有效(在同一输入上)时,该程序仅在某些时候有效。 Specifically, "win" may or may not be printed.具体来说,“win”可能会也可能不会被打印出来。

My program works by creating RowThread, ColumnThread, and GridThread.我的程序通过创建 RowThread、ColumnThread 和 GridThread 来工作。 Each are of them check whether the solution has valid rows, columns and grids, respectively.他们每个人都分别检查解决方案是否具有有效的行、列和网格。 When a thread is finished checking, it calls the appropriate setter method in SudokuTest, which will call the end method in Main if the solution is invalid.当一个线程完成检查时,它会调用 SudokuTest 中适当的 setter 方法,如果解决方案无效,它将调用 Main 中的 end 方法。 If the thread does not determine that the solution is invalid, the setter method will record that the row, column, or grid has been checked, and then call the allChecked method.如果线程没有确定解决方案无效,setter 方法会记录行、列或网格已被检查,然后调用 allChecked 方法。 allChecked checks if row, column, and grid have been checked. allChecked 检查行、列和网格是否已被检查。 If so, then the solution is valid, so it calls Main.success(), which should print "win."如果是,那么解决方案是有效的,因此它调用 Main.success(),它应该打印“win”。 Here is my Main class:这是我的主课:

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();

    }
}

My RowThread class:我的 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();
    }
}

My ColumnThread and GridThread classes are the same as RowThread, except for the logic in the isFail() method.我的 ColumnThread 和 GridThread 类与 RowThread 相同,只是 isFail() 方法中的逻辑不同。 My SudokuTest class:我的数独测试课:

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();
        }
    }
}

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM