java方法同步和读/写互斥

时间:2012-04-29 13:57:51

标签: java multithreading concurrency

我在课程中有以下两种方法read()write()

class Store
{

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

  public string  read()
  {
    // read from store;
  }
}

1)Store对象是单身。

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

我的要求是当作家写信给商店时,所有读者都应该等待。即,当控件位于write()时,应阻止对read()的所有调用。我该如何实现这一目标?我在synchronize(Store.class)方法中尝试了write(),但似乎不适合我。

5 个答案:

答案 0 :(得分: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();
       }
    }
}

答案 1 :(得分:4)

synchronized是最简单的解决方案,所以你应该解释一下“对我来说似乎不起作用”的意思,并且可能告诉我们你是如何使用它的。

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

答案 2 :(得分:2)

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

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

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

public synchronized String read() {
  read from store;
}

然而,这可能有一个缺点:它还禁止两个读取器线程同时读取。如果您确实需要这样做,则应使用ReadWriteLock。但这会导致代码性能降低,难以理解和维护。如果我已经测量到需要,我只会使用它。

答案 3 :(得分:0)

使用java.util.concurrent包中的ReadWriteLock

答案 4 :(得分:0)

请务必阅读本文:

https://blog.takipi.com/java-8-stampedlocks-vs-readwritelocks-and-synchronized/

  • RWLock的速度可能很慢,尤其是当读者人数众多的作家时
  • 同步平均最可靠最快
  • 有新的锁,如StampedLock