同步字段和读写锁有什么区别?



只是想知道以下执行相同功能的代码有何不同

代码 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 时,没有其他线程访问它进行读取,并且在读取时,其他线程不应访问它进行写入。哪个是最佳解决方案,为什么?此外,我将在有需要编辑的字段变量的类中使用它。请提出您的建议。

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

您的两种解决方案都可以使用,但是您实现锁定的方式存在错误。

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

方法中的错误:您要锁定的对象应该是最终的。在 setCount() 中,您有效地交换了对象,这可能会导致此时的脏读。

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

最新更新