簡體   English   中英

帶有Lambda的Sudoku多線程和Java中的Callable

[英]Sudoku Multithreading with lambda and Callable in Java

我制作了一個程序來檢查完成的9x9 Sudoku矩陣是否正確。 我想創建同時檢查行,列和區域以查看數字1-9是否出現在其中的線程。 我是使用Callable和lambda的新手。 到目前為止,這是我的代碼:

public class Sudoku {

    public boolean testBoard(int[][] board) throws InterruptedException, ExecutionException {
        List<Callable<Boolean>> tests = new ArrayList<>();
        tests.add(() -> testCols(board));
        tests.add(() -> testRegions(board));
        tests.add(() -> testRows(board));
        tests.add(() -> testSize(board));

        /*Maybe store this threadPool in a field so you dont create it everytime*/
        ExecutorService threadPool = Executors.newCachedThreadPool();
        List<Future<Boolean>> results = threadPool.invokeAll(tests);

        for (Future<Boolean> future : results) {
            if (!Boolean.TRUE.equals(future.get())) {
                return false;
            }
        }
        return true;
    }

    // check that the board is 9 x 9
    boolean testSize(int[][] board) {
        if (board.length != 9) {
            return false;
        }
        for (int i = 0; i < board.length; i++) {
            if (board[i].length != 9) {
                return false;
            } else;
        }
        return true;
    }

    // check that the digits 1-9 each appear exactly once in the given array
    boolean checkDigits(int[] array) {
        if (array.length != 9) {
            return false;
        }
        int[] counts = new int[10];
        for (int i = 0; i
                < array.length; i++) {
    // invalid number
            if (array[i] < 1 || array[i] > 9) {
                return false;
            }
    // we have already seen this number
            if (counts[array[i]] > 0) {
                return false;
            }
            counts[array[i]]++;
        }
        return true;
    }
    // return true if all rows are correct

    boolean testRows(int[][] board) {
        for (int i = 0; i < board.length; i++) {
            if (!checkDigits(board[i])) {
                return false;
            }
        }
        return true;
    }
    // return true if all columns are correct

    boolean testCols(int[][] board) {
        int[] tmp = new int[board.length];
        for (int col = 0; col < board.length; col++) {
    // fill a temp array with every element of the column
            for (int row = 0; row < board.length; row++) {
                tmp[row]
                        = board[row][col];
            }
    // check to make sure it has all the right digits
            if (!checkDigits(tmp)) {
                return false;
            }
        }
        return true;
    }
    // return true if every region is correct

    boolean testRegions(int[][] board) {
    //loop through each region, passing the indices of the upper-left corner to the next method
    //note that we increment row and column counters by 3 here
        for (int row = 0; row < board.length; row += 3) {
            for (int col = 0; col
                    < board.length; col += 3) {
                if (!testRegion(board, row, col)) {
                    return false;
                }
            }
        }
        return true;
    }
    // test a specific region, given the upper left corner

    boolean testRegion(int[][] board, int startRow, int startCol) {
        int[] tmp = new int[board.length];
    // fill a temporary array with every element of the region
        int index = 0;
        for (int row = startRow; row < startRow + 3; row++) {
            for (int col = startCol; col < startCol + 3; col++) {
                tmp[index]
                        = board[row][col];
                index++;
            }
        }
    // check if we have all of the right digits in the region
        return checkDigits(tmp);
    }
}

public class TestPuzzle {

    public static void testpuzzle() throws FileNotFoundException, InterruptedException, ExecutionException{
        Sudoku sudoku = new Sudoku();
        String fileName = "SudokuRight.txt";//This is for the print statment
        Scanner inputStream = null;
        String[] line;
        System.out.println("The file " + fileName + " contains the following sudoku puzzle:\n");
        inputStream = new Scanner(new File("C:\\Users\\username\\Documents\\NetBeansProjects\\Sudoku\\SudokuRight.txt"));
        int[][] puzzle = new int[9][9];
        int row = 0;
        while (inputStream.hasNextLine()) {
            line = inputStream.nextLine().split(",");
            for (int i = 0; i < 9; i++) {
                puzzle[row][i] = Integer.parseInt(line[i]);
            }
            row++;
        }
        for (int i = 0; i < 9; i++) {
            System.out.println(Arrays.toString(puzzle[i]));
        }

        boolean result = sudoku.testBoard(puzzle);
        System.out.println("Result: " + result);
        if (result == true) {
            System.out.println("This sudoku solution IS valid!");
        } else if (result == false) {
            System.out.println("This sudoku solution IS NOT valid!");
        }
    }
}

public class Main {

    //This is the main method to check the validity of sudoku puzzles
    public static void main(String[] args) throws FileNotFoundException, InterruptedException, ExecutionException {
        TestPuzzle.testpuzzle();
    }
}

有人試圖教我有關使用callable和lambda的知識,但我仍然有些困惑。 我的代碼現在可以正確運行,但是在NetBeans中打印出結果之后,它會繼續運行,直到我手動終止它為止。 我不確定為什么嗎? 我以為我的代碼中必須有一段語句:

Callable<Boolean> callable = () -> Boolean.valueOf(testCols(board));
Callable<Boolean> callable = () -> Boolean.valueOf(testRows(board));
Callable<Boolean> callable = () -> Boolean.valueOf(testRegions(board));
Callable<Boolean> callable = () -> Boolean.valueOf(testSize(board));

但是我不確定在哪里放置這些行? 我不能將它們放在構造函數中,因為“ board”尚未初始化。 我敢肯定這是一個簡單的解決方法,因為我是新手,所以我只是停留在其中。 有什么幫助嗎?

根據我的評論,我認為您的問題是,在將所有Callables添加到其中並調用它們之后,您尚未在執行程序服務上調用shutdown() 我建議您這樣做:

ExecutorService threadPool = Executors.newCachedThreadPool();
List<Future<Boolean>> results = threadPool.invokeAll(tests);
threadPool.shutdown(); // ******* add this! *********

一旦其所有可調用對象完成其操作,這將有助於關閉threadPool。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM