【发布时间】:2015-06-16 09:14:26
【问题描述】:
美好的一天
我有一个关于 ReentrantReadWriteLocks 的问题。我正在尝试解决一个问题,即多个读取器线程应该能够在数据结构上并行操作,而一个写入器线程只能单独操作(而没有读取器线程处于活动状态)。我正在使用 Java 中的 ReentrantReadWriteLocks 来实现这一点,但是从时间测量来看,阅读器线程似乎也在相互锁定。我认为这不应该发生,所以我想知道我是否执行错了。我的实现方式如下:
readingMethod(){
lock.readLock().lock();
do reading ...
lock.readLock().unlock();
}
writingMethod(){
lock.writeLock().lock();
do writing ...
lock.writeLock().unlock();
}
读取方法被许多不同的线程调用。从测量时间来看,读取方法是按顺序执行的,即使写入方法从未被调用!关于这里出了什么问题的任何想法?提前谢谢你-干杯
编辑:我试图提出一个 SSCCE,我希望这很清楚:
public class Bank {
private Int[] accounts;
public ReadWriteLock lock = new ReentrantReadWriteLock();
// Multiple Threads are doing transactions.
public void transfer(int from, int to, int amount){
lock.readLock().lock(); // Locking read.
// Consider this the do-reading.
synchronized(accounts[from]){
accounts[from] -= amount;
}
synchronized(accounts[to]){
accounts[to] += amount;
}
lock.readLock().unlock(); // Unlocking read.
}
// Only one thread does summation.
public int totalMoney(){
lock.writeLock().lock; // Locking write.
// Consider this the do-writing.
int sum = 0;
for(int i = 0; i < accounts.length; i++){
synchronized(accounts[i]){
sum += accounts[i];
}
}
lock.writeLock().unlock; // Unlocking write.
return sum;
}}
我知道读锁内部的部分实际上不是读而是写。我这样做是因为有多个线程执行写入,而只有一个线程执行读取,但是在读取时,不能对数组进行任何更改。这在我的理解中有效。再说一遍,read-Locks 中的代码可以在多个线程中正常工作,只要不添加 write 方法和 read-locks。
【问题讨论】:
-
您的机器上有多少个 CPU 可用?
-
这里没有足够的信息来提供有意义的帮助。这可能是多种原因;简单/幼稚的基准测试技术会在 Java 中产生不一致的结果(正确地对 Java 进行微基准测试确实不容易),您可能在“阅读”中的额外同步中遇到瓶颈,“阅读”的复杂性可能如此之低,以至于线程在它们的时间片内完成,观察到的顺序行为实际上只是上下文切换等的开销。尝试提供一个清楚地证明问题的 SSCCE。
-
如果你说有额外的
synchronized块,你已经自己回答了这个问题…… -
@Holger 经过一番测试,我现在发现了以下几点: 线程以正确的方式进入和退出读取方法(在 lock 和 unlock 语句内),并且不会相互锁定。然而,一个线程完成一次运行该方法所需的时间明显高于没有锁定/解锁的时间。是否有可能,读写锁也出于某种原因阻止所有其他使用的锁,即使它们不是同一个锁对象?我已经在数据结构的不同元素上同步了做阅读,所以不是同一个锁。
-
通常,使用显式锁的理由是获得您所追求的那种控制。同步块使用 Java 中所有对象都具有的隐式锁。如果你所有的读者都在调用 readMethod(),这意味着他们首先从你的 ReadWriteLock 获取读锁,然后获取同步块对象上的隐式锁。由于您没有使用真正的 SSCCE 编辑您的问题,因此只能假设您正在有效地创建一个双重锁,其中内部锁阻止读者同时访问相同的数据结构。
标签: java multithreading concurrency thread-safety locking