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);
}
添加回答
舉報