Tengo esto:
synchronized(c){
if (!items.hasNext() && (c.getFinishedCount() == c.getStartedCount())) {
f.done(null, results);
return;
}
if(c.isBelowCapacity()){
RunMap(items,m,results,c,s,f);
}
}
pero en última instancia no necesito para ser sincronizada en c cuando llamo RunMap()
o f.done()
, sólo hay que estar sincronizados en c cuando lo haga las comprobaciones condicionales / if.
¿Debo hacer que los métodos en C sincronizados, y luego deshacerse del bloque sincronizado?
¿Debo hacer que los métodos en C sincronizados, y luego deshacerse del bloque sincronizado?
No, la mejor manera es hacer que los controles dentro del bloque sincronizado, y luego hacer el resto del trabajo posterior:
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);
}
La gran ventaja de esta versión es que todo el código volátil es realmente sincronizado, y el resto (potencialmente lento) cosas que pasan después.
Como se ha mencionado correctamente en los comentarios a esta respuesta, esto sólo funciona correctamente, si su hipótesis inicial es correcto, que todo el bloque no necesita sincronización. Si tiene que reaccionar a las condiciones de inmediato, entonces el bloque tiene que ser, de hecho, sincronizado (en su totalidad).