当前位置: 代码迷 >> Java相关 >> 范例锁不是只有一把吗?为什么读写锁模式可以多线程同时调用synchronized方法
  详细解决方案

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

热度:6582   发布时间:2013-02-25 21:44:49.0
实例锁不是只有一把吗?为什么读写锁模式可以多线程同时调用synchronized方法?
如题,实例锁只有一把,而synchronized方法会获得实例对象的锁,下面程序是读写锁的线程,我不明白为什么实例锁只有一把,而读写锁可以多线程同时调用读方法,假设读者线程1调用Data中的read方法,进而调用了readLock方法,获得ReadWriteLock的实例锁,那么读者线程2为什么也可以调用这个synchronized限定的readlock方法,此时的锁不是给了线程1吗?线程2没有锁怎么去调用readlock方法呢?
望大神解答,感谢!!!
Java code
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) {        }    }}


------解决方案--------------------------------------------------------
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. 

读锁是不互斥的,只要没有写入者。
------解决方案--------------------------------------------------------
跟wait没有关系,读锁和写锁都是逻辑上的锁,物理锁只有一把就是ReadWriteLock实例的锁,而被读取对象数据Data本身并没有加锁;读读不互斥的实现就是在一个线程readlock之后unreadlock之前释放锁时,另一个读者线程取得实例锁,在取得物理锁这一点上是互斥的,但是在读取数据data时却是不互斥的
  相关解决方案