2 回答
TA贡献1873条经验 获得超9个赞
我应该只使 c 上的方法同步,然后摆脱同步块吗?
不,更好的方法是在同步块中进行检查,然后再做剩下的工作:
boolean bFDone = false;
boolean bRunMap = false;
synchronized (c) {
bFDone = !items.hasNext() && (c.getFinishedCount() == c.getStartedCount());
bRunMap = !bFDone && c.isBelowCapacity();
}
if (bFDone) {
f.done(null, results);
} else if (bRunMap) {
RunMap(items,m,results,c,s,f);
}
这个版本的最大优势是,所有易失性代码实际上都是同步的,其余(可能很慢)的东西会在以后发生。
正如在这个答案的评论中正确提到的那样,如果您的初始假设是正确的,那么这只会正常工作,即整个块不需要同步。如果您需要立即对条件做出反应,那么该块实际上需要(完全)同步。
TA贡献1775条经验 获得超8个赞
使c的方法同步可能是个坏主意。首先,这意味着无论何时调用它们,无论上下文如何,它们都会同步,这可能不是您的意思。其次,它无助于原子地解决条件!items.hasNext()和c.getFinishedCount() == c.getStartedCount().
一种选择是初始化块boolean内的变量synchronized,然后在它们之外执行相关调用:
final boolean isDone;
synchronized(c) {
isDone = !items.hasNext() && (c.getFinishedCount() == c.getStartedCount());
}
if (isDone) {
f.done(null, results);
return;
}
final boolean isBelowCapacity;
synchronized(c) {
isBelowCapacity = c.isBelowCapacity();
}
if (isBelowCapacity) {
RunMap(items,m,results,c,s,f);
}
添加回答
举报