1. 使用技术
2. 涉及到的线程主要的类
- Executors
- 此包java.util.concurrent中定义的Executor,ExecutorService,ScheduledExecutorService,ThreadFactory和Callable类的工厂和实用程序方法。 该类支持以下几种方法:
创建和返回ExecutorService的方法,使用常用的配置设置进行设置。
创建和返回ScheduledExecutorService的方法,使用常用的配置设置进行设置。
创建并返回“包装”ExecutorService的方法,通过使特定于实现的方法不可访问来禁用重新配置。
创建并返回ThreadFactory的方法,该ThreadFactory将新创建的线程设置为已知状态。
从其他类似闭包形式创建和返回Callable的方法,因此可以在需要Callable的执行方法中使用它们。
- ExecutorService
- 继承 Executor 执行者
- 一个Executor(执行者),提供管理终止的方法和可以生成Future以跟踪一个或多个异步任务进度的方法。
可以关闭ExecutorService,这将导致它拒绝新任务。提供了两种不同的方法来关闭ExecutorService。 shutdown方法将允许先前提交的任务在终止之前执行,而shutdownNow方法则阻止等待任务启动并尝试停止当前正在执行的任务。终止时,执行程序没有正在执行的任务,没有等待执行的任务,也没有任何新任务可以提交。应关闭未使用的ExecutorService以允许回收其资源。
方法提交通过创建和返回可用于取消执行和/或等待完成的Future来扩展基本方法Executor.execute(Runnable)。方法invokeAny和invokeAll执行最常用的批量执行形式,执行一组任务,然后等待至少一个或全部完成。 (类ExecutorCompletionService可用于编写这些方法的自定义变体。)
Executors类为此包中提供的执行程序服务提供工厂方法。
- ForkJoinPool
- 体现一个分而治之的思想,其实就是递归算法
- 开启一个新线程(或是重用线程池内的空闲线程),将任务交给该线程处理, 等待该任务的处理线程处理完毕,获得返回值。
3. 涉及的主要的方法
- Executors#newWorkStealingPool() :创建一个和主机核心数量一样多的线程池,使用所有可用处理器作为其目标并行度级别创建工作窃取线程池。
- ExecutorService#invokeAll() : 执行给定的任务,返回完成所有状态和结果的Futures列表。 对于返回列表的每个元素,Future.isDone都为true。 请注意,已完成的任务可能正常终止或通过抛出异常终止。 如果在此操作正在进行时修改了给定集合,则此方法的结果是不确定的。
4. 代码的实现
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Collectors;
public class PrimeCalculationApp {
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newWorkStealingPool();
PrimeCalculationThread server1 = new PrimeCalculationThread(1, 2500);
PrimeCalculationThread server2 = new PrimeCalculationThread(2501, 5000);
PrimeCalculationThread server3 = new PrimeCalculationThread(5001, 7500);
PrimeCalculationThread server4 = new PrimeCalculationThread(7501, 10000);
List<Callable<Integer>> list = Arrays.asList(server1, server2, server3, server4);
Integer collect = executor.invokeAll(list)
.stream()
.map(future -> {
Integer sum = 0;
try {
sum = future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return sum;
}).collect(Collectors.summingInt(Integer::intValue));
System.out.println("素数的数量 : " + collect);
}
}
class PrimeCalculationThread implements Callable<Integer> {
private int start;
private int end;
public PrimeCalculationThread(int start, int end) {
this.start = start;
this.end = end;
}
@Override
public Integer call() throws Exception {
int sum = 0;
int j;
for (int i = start; i <= end; i++) {
j = 2;
for (; j <= Math.sqrt(i); j++) {
if (i % j == 0) {
break;
}
}
if (j > Math.sqrt(i)) {
sum++;
}
}
return sum;
}
}