Найти сумму массива с использованием нескольких потоков

#java #arrays #multithreading

#java #массивы #многопоточность

Вопрос:

Я впервые пытаюсь работать с многопоточностью, поэтому буду признателен за помощь!

Следующая проблема:

Пользователь вводит значения для массива, а также желаемое количество потоков в консоль. Массив должен быть суммирован с использованием этих потоков, и каждый поток находит сумму своего собственного фрагмента в массиве. Итоговый результат должен быть напечатан для каждого потока, а также общая сумма.

 public class Thread1  extends Thread{

    @Override
    public void run() {
        System.out.println("Enter the required size of the array :: ");
        Scanner s = new Scanner(System.in);
        int size = s.nextInt();
        int[] myArray = new int [size];
        System.out.println("Enter the required quantity of the threads :: ");
        int k = s.nextInt();
        int sum = 0;
        System.out.println("Enter the elements of the array one by one ");
        
        for(int i=0; i<size; i  ) {
            myArray[i] = s.nextInt();

            for(int j = 0; j< k; j  ){
                sum = sum   myArray[i];

            }
            System.out.println("Sum for thread: "   this.getName()   " = "   sum);
        }
        System.out.println("Elements of the array are: "  Arrays.toString(myArray));
        System.out.println("Sum of the elements of the array ::" sum);
    }

    public static void main(String[] args) {
        Thread1 t = new Thread1();
        t.start();



    }
}

  

Комментарии:

1. Привет, Яков, добро пожаловать в SO. Пожалуйста, вы должны задать нам один конкретный вопрос и предоставить образец с вашими усилиями. Я предлагаю вам прочитать эту тему, попробовать ее, а затем, на каком-нибудь рабочем примере, мы попытаемся вам помочь. dzone.com/articles /…

2. Эхх, я имею в виду, я знаю, как найти сумму массива. Чего я не понимаю, так это того, как назначать фрагменты массива каждому потоку (извините, если я не ясно выражаюсь, английский не мой родной язык). Я добавил некоторые изменения, но я думаю, что это неправильно

3. вы можете найти решение по URL ниже. codereview.stackexchange.com/questions/123305/… Спасибо 🙂

Ответ №1:

Поскольку это датируется годом назад, я бы упомянул, как я подошел к этому. Во-первых, поскольку использование ExecutorService более поощряется, я использовал это для многопоточности. Также стоит упомянуть, что я не использовал синхронизацию или блокировки, поскольку я не буду делиться никаким значением, и сумма будет вычисляться в конце вместо добавления каждого шага к одной общей сумме.

 public void arraySum(int[] arr){
        start = System.currentTimeMillis();
        ExecutorService exec = Executors.newSingleThreadExecutor();
        sum = 0L;
        int noThreads = 100;
        int length = arr.length/noThreads;
        
        List<Long> res = new ArrayList<>();
        for(int i=0;i<noThreads;i  ) {//each thread
            int low = length*i;
            int high = length low;
            
            res.add(exec.submit(callable(arr, low, high)).get());
        }
                
        exec.shutdown();
        while(!exec.isTerminated());
        if(exec.isTerminated()) {           
            for(long l:res) {               
                sum = l;
            }
        }
        finish = System.currentTimeMillis();
        System.out.println(noThreads " threads: Sum: " sum " Complettion in miliseconds: " (finish -start));
        
    }

    Callable<Long> callable(int[] arr,int low, int high){
        return ()->{
            Long res = 0L;
            for(int i=low;i<high;i  ) {
                res  = arr[i];
            }           
            return res;
        };      
    }

  

Комментарии:

1. если вы хотите использовать это, убедитесь, что вы исправили разделяющую часть, поскольку она использует целочисленное деление, поэтому некоторые элементы могут быть опущены в верхней части.

2. будьте осторожны с тем, как вы вызываете этот метод arraySum с помощью службы исполнителя внутри него. Это тяжелый объект, который должен быть объявлен вне метода.