java 编写一个程序,使用多线程实现并行计算素数的算法,提高计算效率。
时间: 2024-10-14 21:08:03 浏览: 20
在 Java 中,可以使用 `Thread` 类或更现代的 `java.util.concurrent` 包(如 `ExecutorService` 和 `Future`)来编写一个并行计算素数的程序。这里我会展示一个简单的多线程版本,利用 `ForkJoinPool` 来分割任务,它是一个专门为并行计算设计的工具。
```java
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
public class PrimeFinder {
private static final int PRIME_THRESHOLD = 100; // 初始任务大小
private ForkJoinPool pool = new ForkJoinPool();
public List<Integer> findPrimes(int n) {
return primeNumbersTask(n).get();
}
private List<Integer> primeNumbersTask(int limit) {
if (limit <= 1) {
return new ArrayList<>();
} else if (limit <= PRIME_THRESHOLD) {
// 单线程处理小范围
return findPrimesSequentially(limit);
} else {
// 并行处理大范围
int half = limit / 2;
List<PrimeTask> subTasks = new ArrayList<>();
for (int i = PRIME_THRESHOLD; i < half; i++) {
subTasks.add(new PrimeTask(i, i + PRIME_THRESHOLD));
}
List<List<Integer>> results = pool.invokeAll(subTasks);
List<Integer> primes = combineResults(results);
// 继续处理剩余部分
primes.addAll(primeNumbersTask(half));
return primes;
}
}
private List<Integer> findPrimesSequentially(int limit) {
// 单线程计算小范围内的素数
List<Integer> primes = new ArrayList<>();
for (int num = 2; num <= limit; num++) {
if (isPrime(num)) {
primes.add(num);
}
}
return primes;
}
private boolean isPrime(int number) {
if (number <= 1) {
return false;
}
for (int i = 2; i * i <= number; i++) {
if (number % i == 0) {
return false;
}
}
return true;
}
private List<Integer> combineResults(List<List<Integer>> subResults) {
List<Integer> result = new ArrayList<>();
for (List<Integer> subResult : subResults) {
result.addAll(subResult);
}
return result;
}
public static void main(String[] args) {
PrimeFinder finder = new PrimeFinder();
List<Integer> primes = finder.findPrimes(100); // 测试找到100以内的素数
System.out.println("Prime numbers below " + primes.size() + ": " + primes);
}
}
// 定义一个工作单元类
class PrimeTask implements Callable<List<Integer>> {
private final int start;
private final int end;
public PrimeTask(int start, int end) {
this.start = start;
this.end = end;
}
@Override
public List<Integer> call() {
return findPrimesSequentially(end - start);
}
}
```
在这个例子中,`primeNumbersTask` 分解任务成较小的部分,并通过 `ForkJoinPool` 进行并行处理。当任务变得足够小以至于适合单线程处理时,调用 `findPrimesSequentially`。
阅读全文