Guava Striped.get(key) 是否同步?

Is Guava Striped.get(key) synchronized?

我担心 Guava Striped.get(key) 方法是否同步。

那么这个 class 线程安全吗?

class UrlLocker  {
    Striped<Lock> locks = Striped.lazyWeakLock(1);

    public void lock(Url url) {
        locks.get(url).lock();
    }

    public void unlock(Url url) {
        locks.get(url).unlock();
    }
}

或者我是否需要同步我的方法来保护访问锁映射?

要使其完全线程安全,您需要将 locks 实例声明为 final:

class UrlLocker  {
    final Striped<Lock> locks = Striped.lazyWeakLock(1);

    public void lock(Url url) {
        locks.get(url).lock();
    }

    public void unlock(Url url) {
        locks.get(url).unlock();
    }
}

此外,代码的正确性取决于 #hashcode Url class 本身的实现。如果您使用 java.net.URL(看起来不像您那样做),如果您松散 internet connection 如果 DNS 解析会在两次调用之间发生变化,则哈希码会发生变化。

摘自 Striped javadoc:

...assuming {@link Object#hashCode()} is correctly implemented for the keys...

深入研究 guava MapMaker 实现,我发现神奇之处在于方法 com.google.common.collect.ComputingConcurrentHashMap.ComputingSegment#getOrCompu te,它保护计算锁并放入 Map 的临界区。