【发布时间】: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