Java8:如何将for循环转换为并行运行?
我恳求你的帮助。我愿意接受任何建议或批评Java8:如何将for循环转换为并行运行?,java,concurrency,parallel-processing,java-8,java.util.concurrent,Java,Concurrency,Parallel Processing,Java 8,Java.util.concurrent,我恳求你的帮助。我愿意接受任何建议或批评 更新:我能够使用IntStream,任务在28分钟内完成。但我不确定这是否是我所能达到的最佳效果。根据您的情况,您可以使用fork/join框架,或者将executor服务池设置为线程池 IntStream.range(0,20).parallel().forEach(i->{ ... do something here }); 以及使用fork/join框架 ExecutorService service = null;
更新:我能够使用IntStream,任务在28分钟内完成。但我不确定这是否是我所能达到的最佳效果。根据您的情况,您可以使用fork/join框架,或者将executor服务池设置为线程池
IntStream.range(0,20).parallel().forEach(i->{
... do something here
});
以及使用fork/join框架
ExecutorService service = null;
try {
service = Executors.newFixedThreadPool(8);
service.submit(() -> {
//do your task
});
} catch (Exception e) {
} finally {
if (service != null) {
service.shutdown();
}
}
service.awaitTermination(1, TimeUnit.MINUTES);
if(service.isTerminated())
System.out.println("All threads have been finished");
else
System.out.println("At least one thread running");
class RequestHandler扩展了RecursiveAction{
int启动;
内端;
公共请求处理程序(int开始,int结束){
this.start=start;
this.end=end;
}
@凌驾
受保护的void compute(){
如果(end-start对parallel()
的标准调用将为机器上可用的每个内核创建一个线程,减去一个内核,使用
如果您想自己指定并行性,您将有不同的可能性:
更改公共池的并行性:System.setProperty(“java.util.concurrent.ForkJoinPool.common.parallelism”,“20”)
使用自己的池:
例如:
class RequestHandler extends RecursiveAction {
int start;
int end;
public RequestHandler(int start, int end) {
this.start = start;
this.end = end;
}
@Override
protected void compute() {
if (end - start <= 10) {
//REST Request
} else {
int middle = start + (end - start) / 2;
invokeAll(new RequestHandler(start, middle), new RequestHandler(middle, end));
}
}
}
Public class MainClass{
public void main(String[] args){
ForkJoinTask<?> task = new RequestHandler(0, 100000);
ForkJoinPool pool = new ForkJoinPool();
pool.invoke(task);
}
}
这个实现只是给您一个想法的示例。我写了一篇关于这个的短文。它包含一个简单的工具,允许您控制池大小:
我在Java 8中使用了以下代码,它完成了这项工作。我能够将批处理作业的运行时间从28分钟减少到3:39分钟
int allRequestsCount = 20;
int parallelism = 4; // Vary on your own
ForkJoinPool forkJoinPool = new ForkJoinPool(parallelism);
IntStream.range(0, parallelism).forEach(i -> forkJoinPool.submit(() -> {
int chunkSize = allRequestsCount / parallelism;
IntStream.range(i * chunkSize, i * chunkSize + chunkSize)
.forEach(num -> {
// Simulate long running operation
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ": " + num);
});
}));
我愿意接受任何建议或批评!!-我猜你正在受到无声批评IntStream
方法将一次处理相当于计算机中内核数量的请求。如果你想获得更高的速度,请使用异步Http客户端。因此,在得到响应之前不会发生阻塞。@ScaryWombat Lol。我是第二个在!@ImeshaSudasingha,你能提供任何有用的例子吗?谢谢。@ScaryWombat我想沉默的crits在看到“袋熊”后会感到“害怕”他的瓶颈不是在并行处理中,而是在阻塞请求。因此,这不会有任何好处。我以为他在问如何并行分割请求maner@ImeshaSudasingha阻止请求是什么意思?我要求并行分割请求。我要求的是,输入用于发送请求的代码s、 有两种类型的请求。同步请求和异步请求。我想知道您使用的是哪一种请求,因为据我所知,瓶颈与并行性无关。@ImeshaSudasingha如果瓶颈使用的是同步请求而不是异步请求,那么它绝对与并行性有关。请参阅
int allRequestsCount = 20;
int parallelism = 4; // Vary on your own
ForkJoinPool forkJoinPool = new ForkJoinPool(parallelism);
IntStream.range(0, parallelism).forEach(i -> forkJoinPool.submit(() -> {
int chunkSize = allRequestsCount / parallelism;
IntStream.range(i * chunkSize, i * chunkSize + chunkSize)
.forEach(num -> {
// Simulate long running operation
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ": " + num);
});
}));
IntStream.range(0, 100000).parallel().forEach(i->{
restTemplate.exchange(url, HttpMethod.GET, request, String.class);
}
});