我试图将paralleStream与自定义的ForkJoin池一起使用,该任务执行网络调用。当我使用以下样式时
pool.submit(() -> {
ioDelays.parallelStream().forEach(n -> {
induceRandomSleep(n);
});
}).get();
for (final Integer num : ioDelays) {
ForkJoinTask<Integer> task = pool.submit(() -> {
return induceRandomSleep(num);
});
tasks.add(task);
}
int count = 0;
final List<Integer> returnVals = new ArrayList<>();
tasks.forEach(task -> {
try {
returnVals.add(task.get());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});
如果使用parallelStream,那么ForkJoinPool.Common是否以某种方式参与其中?下面是模拟上述两种样式的整个程序
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
public class FJTPExperiment {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ForkJoinPool pool = new ForkJoinPool(200);
List<Integer> ioDelays = new ArrayList<>();
for (int i = 0; i <2000; i++) {
ioDelays.add( (int)(300 *Math.random() + 200));
}
int originalCount = 0;
for (Integer val : ioDelays) {
originalCount += val;
}
System.out.println("Expected " + originalCount);
System.out.println(Thread.currentThread().getName() + " ::::Number of threads in common pool :" + ForkJoinPool.getCommonPoolParallelism());
long beginTimestamp = System.currentTimeMillis();
pool.submit(() -> {
ioDelays.parallelStream().forEach(n -> {
induceRandomSleep(n);
});
}).get();
long endTimestamp = System.currentTimeMillis();
System.out.println("Took " + (endTimestamp - beginTimestamp) + " ms");
List<ForkJoinTask<Integer>> tasks = new ArrayList<>();
beginTimestamp = System.currentTimeMillis();
for (final Integer num : ioDelays) {
ForkJoinTask<Integer> task = pool.submit(() -> {
return induceRandomSleep(num);
});
tasks.add(task);
}
int count = 0;
final List<Integer> returnVals = new ArrayList<>();
tasks.forEach(task -> {
try {
returnVals.add(task.get());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});
endTimestamp = System.currentTimeMillis();
for (Integer val : returnVals) {
count += val;
}
System.out.println("Count " + count);
System.out.println("Took " + (endTimestamp - beginTimestamp) + " ms");
}
public static int induceRandomSleep(int sleepInterval) {
System.out.println(Thread.currentThread().getName() + " ::::sleeping for " + sleepInterval + " ms");
try {
Thread.sleep(sleepInterval);
return sleepInterval;
} catch (InterruptedException e) {
e.printStackTrace();
return sleepInterval;
}
}
}
我最终找到了答案问题有两个部分:
1)只有一个任务被提交给ForkJoinPool,它是如何产生多个线程的?
查看JDK实现,似乎在调用parallelStream时,它会检查当前线程是否是ForkJoinWorkerThread,如果是,则任务会被推送到客户ForkJoinPool的队列中,如果不是,则会被推送到ForkJoinPool.Common。这也通过日志进行了验证。
2)如果它能工作,为什么它慢?
因为并行性不是从自定义ForkJoinPool的并行性派生的,而是从ForkJoinPool.Common的并行性派生的,后者默认情况下限制为CPU核心数-1
。这里是JDK实现,leaf_target
是在这里派生的。如果这必须正常工作,那么应该有一个分支,它从自定义线程池的并行性派生leaf_target
希望你们都平安无事 假设我有以下过程:2个不同的源,队列,延迟,和接收器。我有一个叫“病人”的探员。 我的目标:有不同的服务率(延迟时间)的病人谁是来自第一来源(使用百分比)。换句话说,我想有一个例子;10%的患者(来自源1)延迟时间等于5分钟,90%的患者延迟时间等于10分钟。 我所做的:是我为代理(病人)分配了一个名为“百分比”的参数。并使用我键入的第一个源的“On exit” 然后在延迟时间
我偶然发现了一些毫无意义的东西。我有这个Python代码,它做2个简单的for循环,只是测量执行时间。然而,我发现从一个函数调用完全相同的代码需要一半的时间。有人能解释一下为什么吗? 这里是输出:
https://leetcode.com/problems/find-all-numbers-dispapered-in-an-array/discuss/93007/simple-java-in-place-sort-solution 你能查一下上面的链接吗? 我看不懂密码 然后,第一个只是简单地使用我们可以检查是不是值。 第二个, 它最终也是一样的东西,只是为了证明索引值=index+1。 但
我正在使用Gradle构建系统在Android Studio上编写一个具有多种风格的应用程序。主应用程序/AndroidManifest文件有自己定义的启动程序活动,我想用Flavor/AndroidManifest文件覆盖它,我在其中定义了其他启动程序活动,这些活动只是Flavor/source代码的一部分。 编辑:以下是文件层次结构: 应用程序名称- src公司- 但当我这样做时,它给出了一个
问题内容: 当与MySQL数据库连接时,我有几种方法可以做同样的事情,保存或加载不同类型的参数。目前,我对每种类型都有不同的方法。如何合并这些方法,以便它们支持不同的类型? 下面是两个非常相似但使用不同类型的方法的示例: 请注意,在该示例中,类型均为数字。在类型完全不同的情况下(例如int和String),如何避免使用近乎重复的方法? 问题答案: 您可以在此处应用 策略 模式。 …