java - 该方法是否线程安全并且没有死锁

标签 java concurrency thread-safety deadlock

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();
}

嘿,我只是想请java开发人员检查我的代码是否是线程安全的并且没有死锁,因为我想在我的项目中使用它。 Users、UsersByName 和 UsersByEmail 是 ConcurrentHashMap,其中 String、Integer 作为键,User 对象作为 Value。 UserLocks 是一个 ConcurrentHashMap,以 Integer(显然是用户 id 作为键)和 ReentrantLock 作为值。 我想同步三个HashMap。 如果有人有更好的解决方案来制作具有三个键的并发映射,最好将其发布在这里。性能也很重要。

最佳答案

它是线程安全的。

如果 userId 已在映射中,则代码将获取锁并使用它进行同步。如果没有,ConcurrentHashMap 提供同步以避免对同一 id 使用不同锁的竞争条件。

之后有一段无用的代码,可以去掉:

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

不需要它,因为同步是使用lock.lock()完成的。不需要再次尝试使用 wait()notify() 与锁对象进行同步。(实际上,它并没有按照您的预期工作,多个线程可以调用lock.isLocked() 在同一个锁对象上,并得到 false,直到任何线程调用 lock.lock(),但 lock 和 unlock 之间的所有内容都只被执行一次由一个线程执行)。

此外,通常的良好做法是在finally block 中调用lock.unlock()

关于java - 该方法是否线程安全并且没有死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55005081/

相关文章:

Java并发主题: publication of objects or its internal state

java - Gson处理多个json根元素

java - liferay:如何首先在自动登录 Hook 中强制注销

c# - 多线程应用程序与记录器线程交互

Java并发: Do I have to synchronise a method that only retrieve state and does not modify it?

python - PyTables 线程安全吗?

java - GZIP 压缩对于 64K 的数据效果不佳

java - 骡子 : Mule Studio: Accessing Java class from Mule flow

c++ - 获取线程用于锁定互斥锁

java - Jfreechart索引越界异常