gpt4 book ai didi

java - 并发应用程序不如单线程快

转载 作者:太空宇宙 更新时间:2023-11-04 08:31:39 25 4
gpt4 key购买 nike

我已经实现了管道方法。我要遍历一棵树,我需要某些事先不可用的值...所以我必须并行(或之前)遍历树,并且对于我想要保存值的每个节点再次遍历(例如,descendantCount)。

因此,我通过树进行交互,然后从构造函数调用一个方法,该方法调用通过 ExecutorService 启动的新线程。提交的Callable是:

    @Override
public Void call() throws Exception {
// Get descendants for every node and save it to a list.
final ExecutorService executor =
Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
int index = 0;
final Map<Integer, Diff> diffs = mDiffDatabase.getMap();
final int depth = diffs.get(0).getDepth().getNewDepth();
try {
boolean first = true;
for (final AbsAxis axis = new DescendantAxis(mNewRtx, true); index < diffs.size()
&& ((diffs.get(index).getDiff() == EDiff.DELETED && depth < diffs.get(index).getDepth()
.getOldDepth()) || axis.hasNext());) {
if (axis.getTransaction().getNode().getKind() == ENodes.ROOT_KIND) {
axis.next();
} else {
if (index < diffs.size() && diffs.get(index).getDiff() != EDiff.DELETED) {
axis.next();
}

final Future<Integer> submittedDescendants =
executor.submit(new Descendants(mNewRtx.getRevisionNumber(), mOldRtx
.getRevisionNumber(), axis.getTransaction().getNode().getNodeKey(), mDb
.getSession(), index, diffs));
final Future<Modification> submittedModifications =
executor.submit(new Modifications(mNewRtx.getRevisionNumber(), mOldRtx
.getRevisionNumber(), axis.getTransaction().getNode().getNodeKey(), mDb
.getSession(), index, diffs));
if (first) {
first = false;
mMaxDescendantCount = submittedDescendants.get();
// submittedModifications.get();
}
mDescendantsQueue.put(submittedDescendants);
mModificationQueue.put(submittedModifications);
index++;
}
}

mNewRtx.close();
} catch (final AbsTTException e) {
LOGWRAPPER.error(e.getMessage(), e);
}
executor.shutdown();
return null;
}

因此,对于每个节点,它都会创建一个新的 Callable,它遍历每个节点的树并计算后代和修改(我实际上将两个树修订融合在一起)。嗯,mDescendantsQueue 和 mModificationQueue 是 BlockingQueue。起初,我只有 DescendantsQueue 并再次遍历树以获取每个节点的修改(计算在当前节点的子树中所做的修改)。然后我想为什么不并行执行两者并实现流水线方法。遗憾的是,每次我实现另一个多线程“步骤”时,性能似乎都会下降。

也许是因为 XML 树通常没有那么深,并且并发开销太重:-/

起初我按顺序完成所有操作,这是最快的:- 遍历树- 对于每个节点遍历后代并计算后代计数和修改计数

在使用 BlockingQueues 的流水线方法后,性能似乎有所下降,但我实际上没有进行任何时间测量,我必须恢复许多更改才能返回:(也许性能会随着 CPU 的增加而提高,因为我现在只有一个 Core2Duo 进行测试。

最诚挚的问候,
约翰内斯

最佳答案

也许这应该有所帮助:Amadahl's law ,它基本上说的是生产力的提高取决于(成反比)必须通过同步处理的代码的百分比。因此,即使通过增加更多的计算资源来增加,最终也不会得到更好的结果。理想情况下,如果(同步部分与总部分)的比率较低,则使用(处理器数量+1)应该给出最佳输出(除非您使用网络或其他 I/O,在这种情况下您可以增加池的大小)。因此,只需从上面的链接进行操作,看看是否有帮助

关于java - 并发应用程序不如单线程快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7362035/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com