Java создать многопоточное вычисление простых чисел

2 500 руб. за проект
20 мая 2023, 17:35 • 2 отклика • 29 просмотров
Многопоточное вычисление простых чисел на Java (без использования дополнительных библиотек кроме стандартной)

0. Написать программу, запускающую 2 одинаковых потока (или задания). По-
токи работают параллельно (одновременно).
1. Нужно создать что бы каждый поток должен дописывать в один и тот же файл на диске (Result.txt) разделённые пробелами текстовые записи простых чисел, упорядоченных по возрастанию

Result.txt
2 3 5 7 11 13 17 19
Thread1.txt
2 3 5 13 19
Thread2.txt
7 11 17

2. В отдельном собственном файле (Thread1.txt или Thread2.txt) каждый поток должен со-
хранить те числа (так же через пробел), которые записал в общий файл (Result.txt)
именно он.
3. Числа в файле не должны дублироваться или быть пропущенными.

Я бы не спрашивал если бы знал как разделить. Есть алгоритм, решето Эратосфена:
public static List<Integer> sieveOfEratosthenes(int n) {

boolean[] isPrime = new boolean[n + 1];
Arrays.fill(isPrime, true);

List<Integer> primes = new ArrayList<>();
if (n >= 2) {
primes.add(2);
}

for (int i = 3; i <= n; i += 2) {
if (isPrime[i]) {
primes.add(i);
if (i <= Math.sqrt(n)) {
for (int k = i * i; k <= n; k += 2 * i) {
isPrime[k] = false;
}
}
}
}

return primes;
}
cкорость вычисления на Ryzen 5 5700G 600-700 мс. на 100 млн. чисел (без записи в внешний файл)

вывод осуществляется через отдельный метод где:
void writePrimesToFile(String fileName, List<Integer> primes) {
try (FileWriter writer = new FileWriter(fileName)) {
for (int i : primes) {
writer.write(i + " ");
}
} Работает почти идеально. Но нужно 2 потока и что бы это работало быстрее.
Итого получается 1.1-1.3 сек для 100 млн чисел (то есть n = 100_000_000). всего простых чисел 5761455. Но нужно то же самое только в многопотоке.

У меня никак не получается разделить на потоки что бы каждый поток вычислял своё число и потом всё сливалось в один. Или при больших числах ошибка или медленнее однопотока, но я уверен вы справитесь :)

Лайкфаки типа уже опеределить N в List вроде List <Integer> primes = new ArrayList<>(N); или не определять boolean[] isPrime = new boolean[n + 1]; а в цикле заменить на (!isPrime[i]) и isPrime[k] = true; не сильно дают производительности нужно сделать именно многопоточку что бы каждый поток делал свою работу.

Что нужно: что бы числа считались и выводились в 2 файла как в задании не медленее, а желательно быстрее чем тут. Если сделаете что вычислялось быстрее раза в 1.5-2х то плачe больше (3000). Если больше 2х то 3500.

И желательно комментарии оставить и что бы алгоритм был понятным. Вам не сложно, коментарии я потом удалю.
Отзывы
Avatar r50 a6ce93fe35b158fd29ba0e8681c918c22117160e9586a56eee4ffbc20df9bda1
Заказчик
 
1 год назад
Очнень понятное ТЗ. несмотря на не совсем кореррктную изначальную задачу, общими усилиями удалось рерализовать в рамках допустимых отклонений.
1 год назад