实例锁不是只有一把吗?为什么读写锁模式可以多线程同时调用synchronized方法?

yimixiaoxiong 2012-08-11 03:24:18
如题,实例锁只有一把,而synchronized方法会获得实例对象的锁,下面程序是读写锁的线程,我不明白为什么实例锁只有一把,而读写锁可以多线程同时调用读方法,假设读者线程1调用Data中的read方法,进而调用了readLock方法,获得ReadWriteLock的实例锁,那么读者线程2为什么也可以调用这个synchronized限定的readlock方法,此时的锁不是给了线程1吗?线程2没有锁怎么去调用readlock方法呢?
望大神解答,感谢!!!

public final class ReadWriteLock {
private int readingReaders = 0; // (A)...实际正在读取的执行绪数量
private int waitingWriters = 0; // (B)...正在等待写入的执行绪数量
private int writingWriters = 0; // (C)...实际正在写入的执行绪数量
private boolean preferWriter = true; // 写入优先的话,值为true

public synchronized void readLock() throws InterruptedException {
while (writingWriters > 0 || (preferWriter && waitingWriters > 0)) {
wait();
}
readingReaders++; // (A)实际正在读取的线程数量加1
}

public synchronized void readUnlock() {
readingReaders--; // (A)实际正在读取的线程数量减1
preferWriter = true;
notifyAll();
}

public synchronized void writeLock() throws InterruptedException {
waitingWriters++; // (B)正在等待写入的线程数量加1
try {
while (readingReaders > 0 || writingWriters > 0) {
wait();
}
} finally {1
waitingWriters--; // (B)正在等待写入的线程数量减1
}
writingWriters++; // (C)实际正在写入的线程数量加1
}

public synchronized void writeUnlock() {
writingWriters--; // (C)实际正在写入的线程数量减
preferWriter = false;
notifyAll();
}
}
// 数据类
public class Data {
private final char[] buffer;
private final ReadWriteLock lock = new ReadWriteLock();
public Data(int size) {
this.buffer = new char[size];
for (int i = 0; i < buffer.length; i++) {
buffer[i] = '*';
}
}
public char[] read() throws InterruptedException {
lock.readLock();
try {
return doRead();
} finally {
lock.readUnlock();
}
}
public void write(char c) throws InterruptedException {
lock.writeLock();
try {
doWrite(c);
} finally {
lock.writeUnlock();
}
}
private char[] doRead() {
char[] newbuf = new char[buffer.length];
for (int i = 0; i < buffer.length; i++) {
newbuf[i] = buffer[i];
}
slowly();
return newbuf;
}
private void doWrite(char c) {
for (int i = 0; i < buffer.length; i++) {
buffer[i] = c;
slowly();
}
}
private void slowly() {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
}
}
...全文
133 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
dracularking 2012-08-14
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]
跟wait没有关系,读锁和写锁都是逻辑上的锁,物理锁只有一把就是ReadWriteLock实例的锁,而被读取对象数据Data本身并没有加锁;读读不互斥的实现就是在一个线程readlock之后unreadlock之前释放锁时,另一个读者线程取得实例锁,在取得物理锁这一点上是互斥的,但是在读取数据data时却是不互斥的
[/Quote]
实例锁就一把,为啥能被同时取得呢?
Yx_Ac 2012-08-13
  • 打赏
  • 举报
回复
跟wait没有关系,读锁和写锁都是逻辑上的锁,物理锁只有一把就是ReadWriteLock实例的锁,而被读取对象数据Data本身并没有加锁;读读不互斥的实现就是在一个线程readlock之后unreadlock之前释放锁时,另一个读者线程取得实例锁,在取得物理锁这一点上是互斥的,但是在读取数据data时却是不互斥的
yimixiaoxiong 2012-08-13
  • 打赏
  • 举报
回复
我知道wait会释放锁,但同一时刻不是只有一个线程能通过synchronized取得锁吗?那是如何实现读读不互斥的?[Quote=引用 3 楼 的回复:]

wait会释放对象锁...建议你问的时候,先看一下API或者文档,上面肯定写了这些的。
[/Quote]
dracularking 2012-08-12
  • 打赏
  • 举报
回复
A ReadWriteLock maintains a pair of associated locks, one for read-only operations and one for writing. The read lock may be held simultaneously by multiple reader threads, so long as there are no writers. The write lock is exclusive.

读锁是不互斥的,只要没有写入者。
makai3 2012-08-12
  • 打赏
  • 举报
回复
wait会释放对象锁...建议你问的时候,先看一下API或者文档,上面肯定写了这些的。
yimixiaoxiong 2012-08-11
  • 打赏
  • 举报
回复
自己顶一下,求助呀
yimixiaoxiong 2012-08-11
  • 打赏
  • 举报
回复
求助呀!

50,526

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧