Como se sugiere en varias respuestas a esta pregunta:¿ReadWriteLock hace innecesaria la palabra clave sincronizada?
What is the name of this locking technique?
he implementado un ReentrantReadWriteLock y vi un gran aumento de velocidad (yo sabía que había algo de contención de bloqueo en uno de mi clase y utilizando un bloqueo de reentrada hizo cosas de velocidad ayuda arriba).
Pero ahora me pregunto: si dentro de una clase todos los accesos (tanto de lectura y escritura) se realizan mediante el bloqueo primero una operación de lectura-escritura de bloqueo o un bloqueo, ¿significa la palabra clave sincronizada no debe ser usado más en esa clase?
Por ejemplo, aquí es un funcionario de Java 1.6 ejemplo encontrar en http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html
class RWDictionary {
private final Map<String, Data> m = new TreeMap<String, Data>();
private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
private final Lock r = rwl.readLock();
private final Lock w = rwl.writeLock();
public Data get(String key) {
r.lock();
try { return m.get(key); }
finally { r.unlock(); }
}
public String[] allKeys() {
r.lock();
try { return m.keySet().toArray(); }
finally { r.unlock(); }
}
public Data put(String key, Data value) {
w.lock();
try { return m.put(key, value); }
finally { w.unlock(); }
}
public void clear() {
w.lock();
try { m.clear(); }
finally { w.unlock(); }
}
}
No hay sincronizar palabra clave.
Ahora se dan cuenta de que uno de los puntos de este tipo de cerraduras es ser más rápido que otros métodos (en este caso más rápido que sincronizar), pero ¿cuál es la explicación técnica detrás de esto?
¿El uso de un bloqueo de lectura y escritura en una clase en cada método get/update "reemplaza" la palabra clave sincronizar para estos métodos?
Supongo que estaba sincronizando en la instancia, como 'synchronize (this)'. En cambio, si se sincronizara en dos objetos diferentes, uno para lectura y otro para escritura, habría logrado el mismo rendimiento. Con 'this' sync, cuando' put' se está procesando, innecesariamente 'get' también se espera. Con diferentes objetos de bloqueo, esta contención desaparece. – srkavin
Para la mayoría de las implementaciones de mapas, * es * necesario para hacer que get wait mientras put está en progreso. – Affe
@srkavin La disputa se habría ido, pero también la visibilidad de la memoria garantiza. Su 'get' pudo haber visto una actualización parcial del' put', ya que no estaban sincronizados entre sí. – yshavit