java方法同步和读/写互斥

vij*_*ard 21 java concurrency multithreading

我有两种方法read(),write()如下所示.

class Store
{

  public void write()
  {
    // write to store;
  }

  public string  read()
  {
    // read from store;
  }
}
Run Code Online (Sandbox Code Playgroud)

1)Store对象是单身人士.

2)我有一个Writer写入商店的Reader类和几个同时从商店读取的类.

我的要求是,当作者写信给商店时,所有的读者都应该等待.即,当控制进入时write(),read()应阻止所有呼叫.我该如何实现这一目标?我试过synchronize(Store.class)这个write()方法,但似乎对我不起作用.

Tud*_*dor 37

在这种情况下,最好的选择是使用读写器锁:ReadWriteLock.它允许单个编写器,但允许多个并发读取器,因此它是此类场景的最有效机制.

一些示例代码:

class Store
{
    private ReadWriteLock rwlock = new ReentrantReadWriteLock();

    public void write()
    {
       rwlock.writeLock().lock();
       try {
          write to store;
       } finally {
          rwlock.writeLock().unlock();
       }
    }

    public String read()
    {
       rwlock.readLock().lock();
       try {
          read from store;
       } finally {
          rwlock.readLock().unlock();
       }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @Tudor你应该总是将你的_read包装到store_和_write到_try_块中的store_操作,并确保在相应的_finally_块中使用`unlock()`方法,以防止在发生异常时锁保持锁定状态. (5认同)

Pet*_*rey 5

synchronized 是最简单的解决方案,因此您应该解释“对我来说似乎不起作用”的意思,并可能向我们展示您如何使用它。

更好的解决方案是使用ReentrantReadWriteLock,因为它也允许并发访问读者。


JB *_*zet 5

当一个方法在某个对象上同步时,执行该方法的线程会阻塞所有其他尝试进入在同一对象上同步的另一个块/方法的线程。

因此,如果您希望写入器线程禁止任何读取器线程读取,则必须同步写入和读取方法。没有理由在Store类上同步。在对象上同步Store更加自然:

public synchronized void write() {
  write to store;
}

public synchronized String read() {
  read from store;
}
Run Code Online (Sandbox Code Playgroud)

然而,这(可能)有一个缺点:它还禁止两个读取器线程同时读取。如果您确实需要发生这种情况,您应该使用ReadWriteLock。但这会导致代码性能较低,并且更难以理解和维护。只有当我测量到有必要时,我才会使用它。

  • 为什么你会说“ReadWriteLock”的性能不如“synchronized”?没有充分的技术理由这样做,因为这两种方法都应该只是直接信号量操作的更高级别接口。 (2认同)