同步字段和ReadWriteLocks有什么区别?

问题描述 投票:0回答:2

只想知道具有相同功能的以下代码如何不同

代码1:

    class ReadWriteCounter {
    ReadWriteLock lock = new ReentrantReadWriteLock();

    private Integer count = 0;

    public Integer incrementAndGetCount() {
        lock.writeLock().lock();
        try {
            count = count + 1;
            return count;
        } finally {
            lock.writeLock().unlock();
        }
    }

    public Integer getCount() {
        lock.readLock().lock();
        try {
            return count;
        } finally {
            lock.readLock().unlock();
        }
    }
}

代码2:

class ReadWriteCounter {

private Integer count = 0;

public getCount()
{
   synchronized(count){
   return count;
   }
}

public void setCount(Integer i)
{
     synchronized(count){
         count = i;
       }
   }
}

目的是确保在修改count时没有其他线程访问它以进行读取,并且在读取时没有其他线程应该访问它以进行写入。哪个是最佳解决方案?为什么?另外,我将在一个需要编辑的字段变量的类中使用它。请提供您的建议。

java multithreading synchronization locking thread-synchronization
2个回答
1
投票

ReentrantReadWriteLock是实现您的想法的最佳方式。如果两个或多个线程尝试读取计数,则synchronized将仅允许一个线程。但是当所有人都试图阅读它时,每个人都可以获得计数值。


2
投票

您的解决方案都有效,但是实现锁定的方式存在错误。

首先是两种方法的不同之处:ReentrantReadWriteLock主要用于通常以10次读取的比率写入多于读写的情况:1次写入。这允许读取同时发生而不会相互阻塞,但是当写入开始时,所有读取都将被阻止。因此,性能是主要原因。

您的方法中的错误:您锁定的对象应该是最终的。在setCount()中,您实际上是将对象交换出来,并且可能导致当时的脏读。

此外,永远不要暴露您锁定的对象。您锁定的对象应该是私有的和最终的。原因是如果您碰巧暴露对象,调用者可能会使用返回的对象本身进行锁定,在这种情况下,您将遇到此类本身之外的组件的争用问题。

© www.soinside.com 2019 - 2024. All rights reserved.