同步字段和 ReadWriteLocks 有什么区别?
What is the difference between synchronized fields and ReadWriteLocks?
只是想知道以下具有相同功能的代码有何不同
代码 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 时没有其他线程访问它进行读取,并且在读取时没有其他线程应该访问它进行写入。哪个是最佳解决方案,为什么?此外,我将在 class 中使用它,其中有需要编辑的字段变量。请提出您的建议。
ReentrantReadWriteLock 是实现您的想法的最佳方式。
如果两个或多个线程尝试读取计数,synchronized 将只允许一个线程。
但是每个人都尝试读取它时可以得到count的值。
您的两种解决方案都有效,但是您实施锁定的方式存在错误。
首先两种方式的区别:
ReentrantReadWriteLock 主要用于读取比写入多得多的情况,通常比率为 10 读取:1 写入。这允许读取并发发生而不会相互阻塞,但是当写入开始时,所有读取都将被阻塞。所以性能是主要原因。
您的方法中存在错误:
您锁定的对象应该是最终的。在 setCount() 中,您实际上是在换出对象,这可能会导致脏读。
此外,永远不要暴露您锁定的对象。您锁定的对象应该是私有的和最终的。原因是,如果您碰巧暴露了对象,调用者可能碰巧使用返回的对象本身进行锁定,在这种情况下,您将 运行 陷入与此 class 本身之外的组件的争用问题。
只是想知道以下具有相同功能的代码有何不同
代码 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 时没有其他线程访问它进行读取,并且在读取时没有其他线程应该访问它进行写入。哪个是最佳解决方案,为什么?此外,我将在 class 中使用它,其中有需要编辑的字段变量。请提出您的建议。
ReentrantReadWriteLock 是实现您的想法的最佳方式。 如果两个或多个线程尝试读取计数,synchronized 将只允许一个线程。 但是每个人都尝试读取它时可以得到count的值。
您的两种解决方案都有效,但是您实施锁定的方式存在错误。
首先两种方式的区别: ReentrantReadWriteLock 主要用于读取比写入多得多的情况,通常比率为 10 读取:1 写入。这允许读取并发发生而不会相互阻塞,但是当写入开始时,所有读取都将被阻塞。所以性能是主要原因。
您的方法中存在错误: 您锁定的对象应该是最终的。在 setCount() 中,您实际上是在换出对象,这可能会导致脏读。
此外,永远不要暴露您锁定的对象。您锁定的对象应该是私有的和最终的。原因是,如果您碰巧暴露了对象,调用者可能碰巧使用返回的对象本身进行锁定,在这种情况下,您将 运行 陷入与此 class 本身之外的组件的争用问题。