Java 当数据将在其他线程中更改时实现多线程

Java 当数据将在其他线程中更改时实现多线程,java,multithreading,sudoku,Java,Multithreading,Sudoku,我有一个单线程数独解算器,我想在其中使用多线程。我计划将N个线程委托给板中的每个阵列。每个线程都将返回它们在处理的每个单元格中发现的可能性的数量,从那里我们测试这些值,并在必要时回溯 我一直坚持的是,当一个线程在电路板上插入一个可能的值时,如何保持所有内容的同步,因为它改变了其他线程中的可能数 我正在使用一种称为“最受约束变量”的启发式方法。在每一步中,我们计算每个单元格中的可能性数量,并尝试在该单元格中找到一个具有最小可能候选项的值,以最小化冲突。例如: 1 2 0 0 0 0 0 0

我有一个单线程数独解算器,我想在其中使用多线程。我计划将N个线程委托给板中的每个阵列。每个线程都将返回它们在处理的每个单元格中发现的可能性的数量,从那里我们测试这些值,并在必要时回溯

我一直坚持的是,当一个线程在电路板上插入一个可能的值时,如何保持所有内容的同步,因为它改变了其他线程中的可能数

我正在使用一种称为“最受约束变量”的启发式方法。在每一步中,我们计算每个单元格中的可能性数量,并尝试在该单元格中找到一个具有最小可能候选项的值,以最小化冲突。例如:

 1 2  0 0
 0 0  0 0

 0 0  0 0
 0 0  3 4
第1行第3列的候选项(1)最少,只能放4个。这是算法的核心,也是我想使用多线程并行化的内容

下面是我用来解决数独难题的类:

public class LogicalSolver
{
    private int numberOfSteps;
    public LogicalSolver()
    {
        numberOfSteps = 0;
    }
    public boolean runLogicSolver(SudokuBoard board)
    {
        return logicalSolver(board);
    }
    private boolean logicalSolver(SudokuBoard board)
    {
        boolean solved = false;
        int row = -1;
        int column = -1;
        int candidates[] = new int[board.GRIDSIZE];
        int numOfCandidates = 0;
        for (int currentRow = 0; currentRow < board.GRIDSIZE; currentRow++)
        {
            for (int currentColumn = 0; currentColumn < board.GRIDSIZE; currentColumn++)
            {
                if (board.getValue(currentRow, currentColumn) == 0)
                {
                    int newCandidates[] = getCandidates(board, currentRow, currentColumn);
                    int numOfNewCandidates = getNumOfNewCandidates(newCandidates);
                    if (row < 0 || numOfNewCandidates < numOfCandidates)
                    {
                        row = currentRow;
                        column = currentColumn;
                        candidates = newCandidates;
                        numOfCandidates = numOfNewCandidates;
                    }
                }
            }
        }
        if (row < 0)
        {
            solved = true;
        }
        else
        {
            for (int i = 0; i < candidates.length && candidates[i] != 0; i++)
            {
                board.setValue(row, column, candidates[i]);
                numberOfSteps++;
                if (logicalSolver(board))
                {
                    solved = true;
                    break;
                }
                board.setValue(row, column, 0);
            }
        }
        return solved;
    }
    private int[] getCandidates(SudokuBoard board, int row, int column)
    {
        int newCandidates[] = new int[board.GRIDSIZE];
        int index = 0;
        for (int value = 1; value <= board.GRIDSIZE; value++)
        {
            boolean collision = false;
            for (int offset = 0; offset < board.GRIDSIZE; offset++)
            {
                int rowSubGrid = (row - row % board.ROWS) + (offset / board.ROWS);
                int columnSubGrid = (column - column % board.COLUMNS) + (offset % board.COLUMNS);
                if (board.getValue(row, offset) == value || board.getValue(offset, column) == value
                   || board.getValue(rowSubGrid, columnSubGrid) == value)
                {
                    collision = true;
                    break;
                }
            }
            if (!collision)
            {
                newCandidates[index] = value;
                index++;
            }
        }
        return newCandidates;
    }
    private int getNumOfNewCandidates(int newCandidates[])
    {
        int numOfNewCandidates = 0;
        for (int i = 0; i < newCandidates.length && newCandidates[i] != 0; i++)
        {
            numOfNewCandidates++;
        }
        return numOfNewCandidates;
    }
    public void displayNumberOfSteps()
    {
        System.out.println("It took " + numberOfSteps + " steps to solve this puzzle. \n");
    }
}
公共类逻辑解决方案
{
私有整数步数;
公共逻辑解决方案()
{
numberOfSteps=0;
}
公共布尔runLogicSolver(SudokuBoard)
{
返回逻辑控制器(板);
}
专用布尔逻辑解决方案(SudokuBoard)
{
布尔值=假;
int行=-1;
int列=-1;
int候选者[]=新int[board.GRIDSIZE];
int numf=0;
对于(int currentRow=0;currentRow对于(int-value=1;value,我认为这将是使用ForkJoinTask和ForkJoinPool的好地方

在通往解决方案的每一步中,您都会创建一个新的ForkJoinTask,以探索下一步可能的每一步

每个任务都有其正在研究的状态的副本,因此在设置单元格时无需同步。相反,设置单元格会生成一个新的ForkJoinTask,以探索设置该单元格的后果


如果您必须进行同步,那么您将失去多线程的一些好处。

我认为这将是使用ForkJoinTask和ForkJoinPool的绝佳场所

在通往解决方案的每一步中,您都会创建一个新的ForkJoinTask,以探索下一步可能的每一步

每个任务都有其正在研究的状态的副本,因此在设置单元格时无需同步。相反,设置单元格会生成一个新的ForkJoinTask,以探索设置该单元格的后果


如果你必须进行同步,那么你就失去了多线程的一些好处。

问题是什么?@Jorn Vernee我正试图采用这种算法并使用多线程进行并行化。我明白,但你肯定有一个特定的问题?或者你只是想让别人帮你做吗?@不,我的具体问题是of现在正在决定getCandidates方法中的每个线程如何验证每个单元格,并在发生冲突时向每个线程报告。我已经阅读了有关使用atomic或volatile的内容,但无法决定在该实例中使用哪个更好。@jorn Vernee还说,在这种情况下使用哪个更好?FixedSizeThreadPool还是cacheSizeThreadPool?我认为FixedSizePool是因为电路板中的每个阵列只需要一个线程。问题是什么?@Jorn Vernee我正在尝试使用这个算法并使用多线程进行并行化。我理解,但你肯定有一个特定的问题?或者你只是想让别人帮你做吗?@不,我目前的具体问题是决定性的如果发生冲突,GetPendidates方法中的每个线程如何验证每个单元格并向每个线程报告。我已经阅读了有关使用原子或volatile的内容,但无法决定在这个实例中使用哪个更好。@jorn Vernee也知道在这种情况下使用哪个更好?FixedSizeThreadPool还是cacheSizeThreadPool?我想修复edSizePool,因为我们板中的每个阵列只需要一个线程。谢谢你的提示,但是如果你不介意的话,我们可以在聊天室中讨论更多吗?解决方案应该是公开的,以帮助其他访问该网站的访问者,而不是在私人聊天中。我不想破坏“边做边学”通过给你太多的信息。我将在接下来的几个小时内登录chat.stackoverflow.com。谢谢你的提示,但是如果你不介意的话,我们可以在聊天室里谈论更多吗?解决方案应该是公开的,以帮助网站的其他访问者,而不是在私人聊天中。我不想破坏“lear”