¿Funcionará este método sin hilos y sin puntos muertos?

public int saveUserToMap(User user) {
    ReentrantLock lock;
    if(this.userLocks.containsKey(user.getId())) {
        lock = this.userLocks.get(user.getId());
    } else {
        lock = new ReentrantLock();
        ReentrantLock check = this.userLocks.putIfAbsent(user.getId(), lock);
        if(check != null)
            lock = check;
    }

    if(lock.isLocked())
        try {
            lock.wait();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    lock.lock();

    this.users.put(user.getId(), user);
    this.usersByName.put(user.getUsername(), user);
    this.usersByEmail.put(user.getEmail(), user);

    lock.unlock();
    lock.notify();

    return user.getId();
}

Oye, solo quiero pedirle a los desarrolladores de Java que verifiquen mi código si será seguro para subprocesos y sin Deadlocks, ya que quiero usarlo en mi proyecto. Users, UsersByName y UsersByEmail son ConcurrentHashMap con String, Integer como clave y User object como Value. UserLocks es un ConcurrentHashMap con Integer (obviamente, la identificación del usuario como clave) y un ReentrantLock como valor. Quiero sincronizar los tres HashMaps. Si alguien tiene una mejor solución para hacer un mapa concurrente con tres claves, sería bueno publicarlo aquí. El rendimiento también es importante.

Respuesta 1

Es seguro para hilos.

Si el ID de usuario ya está en el mapa, el código obtiene el bloqueo y lo usa para sincronizar. Si no, ConcurrentHashMapproporciona la sincronización para evitar una condición de carrera para usar diferentes bloqueos para la misma identificación.

Después de eso, hay un fragmento de código inútil, puede deshacerse de él:

if(lock.isLocked())
    try {
        lock.wait();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

No es necesario porque la sincronización se está haciendo usando lock.lock(). No es necesario intentar sincronizar nuevamente usando wait()y notify()con el objeto de bloqueo. (En realidad, no funciona como esperaba, varios subprocesos pueden invocar lock.isLocked()el mismo objeto de bloqueo y obtener un falso hasta que cualquiera de los subprocesos llame lock.lock(), pero todo entre bloqueo y el desbloqueo solo lo ejecuta un solo subproceso a la vez).

Además, una buena práctica habitual es llamar al lock.unlock()bloque finalmente.

Respuesta: 2

Sé que la forma más sencilla de hacerlo es cambiar manualmente la variable PATH, pero ¿cuál podría ser la razón si este cambio no hace ninguna diferencia? Esta es mi ruta variable del sistema: C: \ Archivos de programa \ RSA ...

Soy nuevo en JMX y quiero administrar (o monitorear) mi aplicación jsp-servlet, con muchos servlets y archivos JSP ejecutándose en Tomcat. Hice una aplicación de demostración simple que fue dada por Oracle ...

Posible duplicado: Pase el punto y coma en Ant como parámetro. Tengo que leer este XE de esta etiqueta de atributo xml <database key = "Test" type = ". Configdb"> <dbname> test </dbname> ...

Estoy tratando de crear una aplicación de Android (Nivel mínimo de API 23, Android Studio 3.3.2, Uso de artefactos AndroidX) donde un usuario puede registrarse e iniciar sesión; Todos los datos deben almacenarse en Cloud Firestore. Mi entrada ...