Я введу некоторое число для вычисления суммы ряда Факториала, например, если я поставлю 5, результат будет 1! +2! +3! +4! +5 !, но вычислительная обработка может быть тяжелой, поэтому я хочу использовать несколько шагов, вычисляет каждый факториал .. означает, что thread1 cals 1 !, thread2 cals 2! ... я использовал массивы потоков, но не могу синхронизировать их в результатах propel. и не могу найти способ суммировать эти результаты.

Я написал коды ...

public class Calthread extends Thread{
    private int num=1;
    public Calthread(int num) {
        this.num = num;
    }

    public void run() {
        int dft = 1;
        for(int i=1; i<=num; i++) {
            dft = dft*i;
        }
        System.out.println(num + "! result :" + dft);
    }

}

Это для 1 потока

Для основного класса

public class calculator {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("input number>>");
        int k = scanner.nextInt();  //input 'k'

        int sum = 0;

        Calthread[] cal = new Calthread[k]; // make threads number of 'k'
        for(int i = 0; i<k; i++) {
            cal[i] = new Calthread(i+1);
            cal[i].start();
        }
    }

}

Как я могу синхронизировать их и распечатать сумму всех?

1
hyung jun cho 17 Ноя 2019 в 14:55

1 ответ

Лучший ответ

Чтобы вернуть значение из потока, вы должны использовать Callable вместо Runnable:

public class Calthread implements Callable<Integer> {

    private int num = 1;

    public Calthread(int num) {
        this.num = num;
    }

    @Override
    public Integer call() {
        int dft = 1;
        for (int i = 1; i <= num; i++) {
            dft = dft * i;
        }
        return dft;
    }
}

И в основном классе:

public class Calculator {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("input number>>");
        int k = scanner.nextInt();  //input 'k'

        int sum = 0;
        // Make threads number of 'k'. Here we use List instead of array because there is such contract in ExecutorService
        List<Calthread> cal = new ArrayList<>(k);
        // Create thread pool with fixed number of threads
        ExecutorService service = Executors.newFixedThreadPool(k);
        // Add all Callable task in one collection
        for (int i = 0; i < k; i++) {
            cal.add(new Calthread(i+1));
        }
        try {
            // Invoke all Callable task and get List with results
            List<Future<Integer>> results = service.invokeAll(cal);
            // Future::get is blocking method. It waits result.
            for (Future<Integer> result : results) {
                sum += result.get();
            }
        } catch (InterruptedException | ExecutionException e) {
            System.out.println("Something went wrong");
            e.printStackTrace();
        }

        System.out.println("Result: " + sum);
        // We need to shutdown our service
        service.shutdown();
    }
}
1
Roman Danilov 17 Ноя 2019 в 12:15