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