Java 同时读取但通过编辑锁定

Java 同时读取但通过编辑锁定,java,multithreading,java.util.concurrent,Java,Multithreading,Java.util.concurrent,我正在寻找一种解决方案,允许多个线程读取共享资源(允许并发),但一旦线程进入变异块,就会锁定这些读取线程,以实现两者的最佳效果 class Foo { Map<String, String> sharedResource; public void read() // multiple reading threads allowed, concurrency ok, lock this only if a thread enters the mutating blo

我正在寻找一种解决方案,允许多个线程读取共享资源(允许并发),但一旦线程进入变异块,就会锁定这些读取线程,以实现两者的最佳效果

class Foo {

    Map<String, String> sharedResource;

    public void read() // multiple reading threads allowed, concurrency ok, lock this only if a thread enters the mutating block below.
    {
         // read concurrently unless a thread enters mutating blocks add/remove
    }

    public void add() // this should lock any threads entering this block as well as lock the reading threads above
    {
        synchronized(sharedResource) // lock remove and read
        {
        }
    }

    public void remove() // lock add and read
    {
        synchronized(sharedResource)
        {
        }
    }
}
class-Foo{
地图共享资源;
public void read()//允许多个读取线程,并发正常,仅当线程进入下面的变异块时才锁定此线程。
{
//除非线程进入变异块添加/删除,否则并发读取
}
public void add()//这将锁定进入此块的所有线程,并锁定上面的读取线程
{
已同步(sharedResource)//锁移除和读取
{
}
}
public void remove()//锁定添加和读取
{
已同步(共享资源)
{
}
}
}

Java中有这样的解决方案吗?

这是一个经典的读/写锁定方案:

class Foo {

    Map<String, String> sharedResource;
    ReadWriteLock lock = new ReentrantReadWriteLock();

    public void read() {
         lock.readLock().lock();
         try {
             // read
         } finally {
             lock.readLock().unlock();
         }
    }

    public void add() {
         lock.writeLock().lock();
         try {
             // add
         } finally {
             lock.writeLock().unlock();
         }
    }

    public void remove() {
         lock.writeLock().lock();
         try {
             // remove
         } finally {
             lock.writeLock().unlock();
         }
    }
}
class-Foo{
地图共享资源;
ReadWriteLock lock=new ReentrantReadWriteLock();
公共无效读取(){
lock.readLock().lock();
试一试{
//阅读
}最后{
lock.readLock().unlock();
}
}
公共无效添加(){
lock.writeLock().lock();
试一试{
//加
}最后{
lock.writeLock().unlock();
}
}
公共空间删除(){
lock.writeLock().lock();
试一试{
//除去
}最后{
lock.writeLock().unlock();
}
}
}

读锁可以共享,但写锁对读和写都是独占的。

这是一种经典的读/写锁方案:

class Foo {

    Map<String, String> sharedResource;
    ReadWriteLock lock = new ReentrantReadWriteLock();

    public void read() {
         lock.readLock().lock();
         try {
             // read
         } finally {
             lock.readLock().unlock();
         }
    }

    public void add() {
         lock.writeLock().lock();
         try {
             // add
         } finally {
             lock.writeLock().unlock();
         }
    }

    public void remove() {
         lock.writeLock().lock();
         try {
             // remove
         } finally {
             lock.writeLock().unlock();
         }
    }
}
class-Foo{
地图共享资源;
ReadWriteLock lock=new ReentrantReadWriteLock();
公共无效读取(){
lock.readLock().lock();
试一试{
//阅读
}最后{
lock.readLock().unlock();
}
}
公共无效添加(){
lock.writeLock().lock();
试一试{
//加
}最后{
lock.writeLock().unlock();
}
}
公共空间删除(){
lock.writeLock().lock();
试一试{
//除去
}最后{
lock.writeLock().unlock();
}
}
}

读锁可以共享,但写锁对读和写都是独占的。

感谢这个例子,这似乎是我在
C#
中使用的
ConcurrentDictionary
中的一个快速问题,您如何看待java中的
ConcurrentHashMap
,这与你给我的答案类似吗?假设它实际上是我们正在讨论的一个映射,那么在一些映射实现中进行读取实际上会改变映射:。您需要确保Map实现与锁定策略一致。此外,还有一些Map实现可以有效地允许多个读卡器无需外部锁定:。@user2727195
ConcurrentHashMap
通常是类似您的情况下的推荐解决方案。ok。这可能是低效的,但仅仅是为了信息,如果我将所有方法(
read
add
remove
)标记为
synchronized
,这与使用您的答案以及使用
ConcurrentHashMap
(当然没有同步方法)基本相同吗?@JohnH这很有趣。我一直听说在一些map实现中可能会使用livelock,但我没有考虑到有些map会显式地在
get()
上编写。虽然你的评论可能与这个问题比我的答案更相关。感谢这个例子,这似乎是我在
C#
中使用的
ConcurrentDictionary
中的一个快速问题,你对java中的
ConcurrentHashMap
有何看法,这与你给我的答案类似吗?假设它实际上是我们正在讨论的一个映射,那么在一些映射实现中进行读取实际上会改变映射:。您需要确保Map实现与锁定策略一致。此外,还有一些Map实现可以有效地允许多个读卡器无需外部锁定:。@user2727195
ConcurrentHashMap
通常是类似您的情况下的推荐解决方案。ok。这可能是低效的,但仅仅是为了信息,如果我将所有方法(
read
add
remove
)标记为
synchronized
,这与使用您的答案以及使用
ConcurrentHashMap
(当然没有同步方法)基本相同吗?@JohnH这很有趣。我一直听说在一些map实现中可能会使用livelock,但我没有考虑到有些map会显式地在
get()
上编写。尽管你的评论与问题的相关性比我的回答更大。