- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试 Java 中的执行程序服务,并编写了以下代码来运行斐波那契数列(是的,大规模递归版本,只是为了强调执行程序服务)。
令人惊讶的是,如果我将nThreads设置为1,它会运行得更快。这可能与提交给执行器服务的每个“任务”的大小非常小有关。但如果我将 nThreads 设置为 1,它仍然必须是相同的数字。
为了查看对共享原子变量的访问是否会导致此问题,我用注释“see text”注释掉了这三行,并查看系统监视器以查看执行需要多长时间。但结果是一样的。
知道为什么会发生这种情况吗?
顺便说一句,我想将它与 Fork/Join 的类似实现进行比较。事实证明它比 F/J 实现慢得多。
public class MainSimpler {
static int N=35;
static AtomicInteger result = new AtomicInteger(0), pendingTasks = new AtomicInteger(1);
static ExecutorService executor;
public static void main(String[] args) {
int nThreads=2;
System.out.println("Number of threads = "+nThreads);
executor = Executors.newFixedThreadPool(nThreads);
Executable.inQueue = new AtomicInteger(nThreads);
long before = System.currentTimeMillis();
System.out.println("Fibonacci "+N+" is ... ");
executor.submit(new FibSimpler(N));
waitToFinish();
System.out.println(result.get());
long after = System.currentTimeMillis();
System.out.println("Duration: " + (after - before) + " milliseconds\n");
}
private static void waitToFinish() {
while (0 < pendingTasks.get()){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
executor.shutdown();
}
}
class FibSimpler implements Runnable {
int N;
FibSimpler (int n) { N=n; }
@Override
public void run() {
compute();
MainSimpler.pendingTasks.decrementAndGet(); // see text
}
void compute() {
int n = N;
if (n <= 1) {
MainSimpler.result.addAndGet(n); // see text
return;
}
MainSimpler.executor.submit(new FibSimpler(n-1));
MainSimpler.pendingTasks.incrementAndGet(); // see text
N = n-2;
compute(); // similar to the F/J counterpart
}
}
运行时间(大约):
更新:我注意到,即使我在执行程序服务中使用一个线程,整个程序也会使用我机器的所有四个核心(每个核心平均使用率约为 80%)。这可以解释为什么在执行程序服务中使用更多线程会减慢整个进程的速度,但是现在,如果执行程序服务中只有一个线程处于 Activity 状态,为什么这个程序要使用 4 个核心?
最佳答案
It might be related to the fact that the size of each "task" submitted to the executor service is really small.
情况确实如此,因此您主要测量上下文切换的开销。当n == 1时,没有上下文切换,因此性能更好。
But still it must be the same number also if I set nThreads to 1.
我猜你在这里的意思是“高于1”。
您遇到了严重的锁争用问题。当您有多个线程时,结果
上的锁始终处于竞争状态。线程必须互相等待才能更新结果
,这会减慢它们的速度。当只有一个线程时,JVM 可能会检测到这一点并执行锁省略,这意味着它实际上根本不执行任何锁定。
如果您不将问题划分为 N
个任务,而是将其划分为 N/nThreads
个任务,那么您可能会获得更好的性能,这些任务可以通过线程(假设您选择的 nThreads 最多为可用物理核心/线程的数量)。然后,每个线程执行自己的工作,计算自己的总数,并仅在线程完成时将其添加到总计中。即便如此,对于 fib(35)
我预计线程管理的成本将超过其 yield 。也许可以尝试fib(1000)
。
关于java - Java ExecutorService 上的 Fibonacci 顺序运行比并行运行更快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13644222/
我有一个executorService,它不等待executorService部分完成,它直接返回返回值而不等待下面是我的代码:请查看我是否正确实现了executorService,并在需要时帮助我纠
我有一个运行在另一个执行器服务中的执行器服务来发送电子邮件。如果我在外部执行程序上调用关闭,它正在等待内部执行程序服务关闭,这会极大地影响响应时间。 private final ExecutorSer
我有两个 ExecutorService 实例:一个有 4 个线程,另一个有 20 个线程。我希望单击按钮后,服务 1 就会停止并等待服务 2 结束。之后,服务1继续运行。 我尝试使用 wait 和
我目前有一个 ExecutorService,我想要以下内容: 不应接受任何新任务。 当前任务仍应继续执行。 应返回所有当前排队的任务。 我面临的问题是 shutdown() 不会返回任何未执行的已提
/** * Blocks until all tasks have completed execution after a shutdown * request, or the timeout o
我在线程 A 上创建 ExecutorService,然后线程 B 在 ExecutorService 上调用 shutdown() 和 awaitTermination()。 假设在线程B创建之前所
为了提高请求的响应时间,我打算使用 executorService 并将工作分配给多个线程,以减少请求的响应时间。 但是在阅读文章和博客后,为每个请求创建新的线程池也会影响性能。 闲置方法是什么,-1
我正在学习使用 ExectorService 来汇集 threads 并发送任务。我下面有一个简单的程序 import java.util.concurrent.ExecutorService; im
这是我为暴露我的问题所做的一个简化示例。我有任务doSomeWork()我使用 ExecutorService(一次最多 4 个线程)以多线程方式处理。但是,如果任何线程/任务产生异常,我想: 停止处
我的类路径中有 Guava ,想使用 ListenableFuture s,但目前我不知道如何提交ListenableFuture s 还是目前只能在调用线程中没有执行程序的情况下使用它们?我读过 r
我正在学习 ExecutorService 和 Callables,但收到来自 intelij 的警告,说我正在为此行进行未经检查的分配: Future> future = executorServi
我正在编写一个 Java Fractal Explorer,分形计算是多线程完成的。以前,我只是创建了一堆线程(与系统有处理器内核一样多)并将它们保存在一个数组中,但这会导致一些问题并且不是很优雅,现
我想加入两个在 ExecutorService 中执行的线程。 public class CURD { public static ExecutorService executorService
我有一个工作单元列表,我想并行处理它们。每个单元工作 8-15 秒,完全计算时间,没有 I/O 阻塞。我想要实现的是拥有一个 ExecutorService那: 当没有工作要做时,实例化的线程为零 如
我想同时向最多 10 个用户发送 ping,并在 ping 完成后用结果更新用户对象。 为了做到这一点,我尝试使用 ExecutorService . 我从这样的代码开始: private void
我有一个在 ForkJoinPool 线程池中执行的递归批量任务。 public class SomeTask extends RecursiveAction { @Override
我有一个要遍历的列表,并且对于列表中的每个值都将调用一个方法。现在我已经将相关方法放在一个线程中,并使用执行器服务来并行处理这些方法。但是,对于列表中的每个值,该方法最终会由于某种原因被调用两次。 E
这个问题已经有答案了: How to wait for all threads to finish, using ExecutorService? (27 个回答) 已关闭 4 年前。 我正在尝试使用
我有一个基于ExecutorService线程流量调节的问题:我想 .submit() 多个线程来执行,我希望一些线程等待,直到特定的先前线程完成执行。 。 到目前为止,我知道一种通过使用 Count
我想知道这段代码是否正确。当我在构造对象本身时将可运行对象提交给执行器服务时,这不会导致问题吗? public class A implements Runnable { public
我是一名优秀的程序员,十分优秀!