首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ReentrantReadWriteLock和同步块

ReentrantReadWriteLock和同步块
EN

Stack Overflow用户
提问于 2014-04-23 21:01:12
回答 2查看 276关注 0票数 0

如果我有一个ReentrantReadWriteLock,并将它用作同步块中的锁,其他线程还能释放它们的锁吗?

例如:

代码语言:javascript
复制
ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);

public void doSomething() {
    synchronized(lock) {
        lock.readLock().lock();
        // do stuff
        lock.readLock().unlock();
    }
}

如果我调用doSomething(),而另一个线程已经持有读锁,那么该线程能释放读锁吗?

当我进行doSomething()调用时,我将在ReentrantReadWriteLock上同步,然后尝试获取读锁。由于某些东西已经保存了读锁,我将阻塞直到该锁被释放。我很想知道读锁是否可以释放,因为我已经同步了锁本身。

EN

回答 2

Stack Overflow用户

发布于 2014-04-23 21:28:57

在ReentrantReadWriteLock对象上同步似乎是一个非常糟糕的主意。您的示例是锁定两个完全独立的锁。首先,它将内置到每个对象(在本例中为ReentrantReadWriteLock对象)的互斥锁锁定,然后锁定读取锁。

每当你看到一个锁时,你都应该问这个问题:“锁应该保护的不变量是什么?”这是另一种问:“如果锁不存在,您的数据会以什么方式被破坏?”

好的,synchronized(lock)保护什么?

那么,lock.readLock().lock()保护什么呢?

如果两个答案是相同的,那么为什么使用两个锁呢?

如果由我来决定的话,我一开始就不包括读/写锁

您不妨将您的示例更改为:

代码语言:javascript
复制
Object lock = new Object();

public void doSomething() {
    synchronized(lock) {
        // do stuff
}

就您向我们展示的代码而言,它的行为不会有任何不同。(尽管如此,它可能会改变您的示例与您尚未向我们展示的其他代码的交互方式。)

票数 1
EN

Stack Overflow用户

发布于 2014-04-23 21:40:37

编写一个示例非常简单,该示例显示一个在实际锁对象上保存监视器的线程不会阻碍其他线程获取和释放读锁。(当然,这并没有被实际记录下来,所以在理论上,对于另一个Java实现来说可能是不同的!)

代码语言:javascript
复制
public static void main(String[] args) throws Exception {
    final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);

    synchronized (lock) {
        lock.readLock().lock();
        try {
            for (int i = 0; i < 10; i++) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        lock.readLock().lock();
                        try {
                            System.out.println("foo");
                        } finally {
                            lock.readLock().unlock();
                        }
                    }
                }).start();
            }
            Thread.sleep(500);
            System.out.println("done");
        } finally {
            lock.readLock().unlock();
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23255083

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档