java - "synchronized-with-resource"获取锁对象也必须同步怎么办?

标签 java multithreading parallel-processing synchronization synchronized

我有一个Map<String, Mutex> m我想锁定互斥锁,同时确保获取锁的行为是线程安全的:

//Assuming till here m.get(key) return a non-null value
synchronized (Mutex mtx = m.get(key)) {
  mtx.count++;
  //...
}

Java 中不保证以下内容

Mutex mtx = m.get(key);
synchroinzed (mtx) {
  //thread 2 may acquire lock before thread 1 even thread 1 execute first
}

两者都不是

synchronized (m.get(key)) {
  Mutex mtx = m.get(key); 
  //mtx could be null if other threads remove the key between 2 statements
  //because lock is only acquired on m.get(key), not m itself
}

我怎样才能安全地实现这一目标?

<小时/>

编辑:

我现在的确切代码:

public static <T, V> void lock (Map<T, Mutex<V>> mm, T uniqueKeyValue1, long waitMs) throws Mutex.WaitTimeoutException, InterruptedException {

    synchronized ( MapUtils.putIfAbsentRetNewVal(mm, uniqueKeyValue1, new Mutex<V>()) ) {

        Mutex<V> m = mm.get(uniqueKeyValue1);

        if (m.getLockCount() == 0) {
            m.incrementLockCount();
        }
        else {
            m.incrementLockCount();

            m.wait(waitMs);

            if (m.getValue() == null) {
                throw new Mutex.WaitTimeoutException();
            }
        }
    }

}

最佳答案

这不是问题,与资源没有任何关系。使用选项 2。您所要求的并不能解决该问题。您需要的不是资源,而是在 map 上同步,然后在互斥体上同步,然后在 map 上释放同步的东西。由于静态作用域,您无法通过同步来实现这一点。

您实际上需要的是另一个互斥体。或者,直接接受比赛。这是良性的。您不关心哪个线程首先执行。

关于java - "synchronized-with-resource"获取锁对象也必须同步怎么办?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32980412/

相关文章:

c - 在 Open MPI 中处理图像 block

java - 导入自己的枚举转换器

java - 将对象添加到列表

java - 密码强度检查库

java - 在 Java 中向线程发出信号

c# - 避免 hangfire 作业重复的技巧?

c# - 通过异步示例了解 C# 中的并行编程

java - T 类型数组(Java 泛型)

java - 用于在框架内的面板上显示不同半径的圆的代码

java - 对具有不同线程数的两个对象使用 CycleBarrier