ReadWriteLock是否不必渲染synchronized关键字?

Ced*_*tin 7 java synchronization locking

正如在这个问题的几个答案中所建议的:

这种锁定技术的名称是什么?

我实现了一个ReentrantReadWriteLock并且看到了一个很好的加速(我知道在我的一个类中有一些锁争用并且使用重入锁确实有助于加快速度).

但现在我想知道:如果在一个类中,所有访问(读取和写入)都是通过首先锁定读锁定或写锁定来完成的,是否意味着不应该在该类中使用synchronized关键字?

例如,这是http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html上的一个官方Java 1.6示例.

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(); }
    }
 }
Run Code Online (Sandbox Code Playgroud)

没有synchronize关键字.

现在我意识到这种锁的一个要点是比其他方法更快(在这种情况下比同步更快)但这背后的技术解释是什么?

在每个get/update方法的类中使用读写锁是否"替换" 这些方法的synchronize关键字?

ysh*_*vit 11

如果您读取ReadWriteLock和Lock上的javadoc,他们特别说Locks必须提供与synchronized关键字相同的内存语义:

所有Lock实现必须强制执行内置监视器锁提供的相同内存同步语义,如Java语言规范,第三版(17.4内存模型)中所述:

(那是来自Lock javadoc; ReadWriteLock引用Lock来描述它的语义.)

所以,是的,它取代了synchronized关键字.事实上,你可以synchronized用一个Lock 替换你代码中的每个块并具有相同的语义(并且,取决于jvm,甚至可能是一个小的性能提升.)但是你会以更快的速度交易一点速度,如果你忘记解锁其中一个锁,你可能会使你的程序陷入僵局.

很多这方面的功能是非阻塞算法(比较和交换是它们的核心)与volatile字段的内存语义相结合,它们指定如果你写入一个volatile字段,那么随后读取该字段的任何线程都必须在当你写这个世界时,你所看到的世界状态至少相同.(他们也可以看到写完之后发生的部分或全部内容.)这些工具可以制作一些相当快的代码,但它们也很微妙且容易出错 - 几乎总是最好留在更高级别构造(例如您正在使用的ReadWriteLock).