【Java】ReadWriteLock浅谈

一,概述

在多读少写的场景下,可以使用读写锁优化性能。读锁本质是一种共享锁,即,如果ReadLock获取锁成功,只会阻塞WriteLock锁的获取,不会阻塞其它线程ReadLock锁的获取。而写锁就是正常的独占锁。

二,简单实例

一个简单demo,读者可体会。

public static void main(String[] args) {
        ReadWriteLock lock = new ReentrantReadWriteLock();

        Lock readLock = lock.readLock();

        Lock writeLock = lock.writeLock();

        for (int i = 0; i < 8; i++) {
            int finalI = i;
            if (i == 3){
                new Thread(() -> {
                    writeLock.lock();
                    System.out.println("acquire write");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    System.out.println("release write");
                    writeLock.unlock();
                }).start();
            }else{
                new Thread(() -> {
                    readLock.lock();
                    System.out.println("acquire read" + finalI);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    System.out.println("release read" + finalI);
                    readLock.unlock();
                }).start();
            }
        }


        try {
            Thread.sleep(100000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
打印台:

acquire read0
acquire read2
acquire read1
release read2
release read1
release read0
acquire write    //写锁获取了锁
release write
acquire read4
acquire read6
acquire read5
acquire read7
release read4
release read5
release read6
release read7

以上控制台输出可知,读锁释放前,读锁可供其它线程共享获取。但当写锁开始获取时,后续读锁的获取阻塞,加入AQS队列。仅当写锁释放后,读锁才可继续获取。

官方给了使用例子如下,可以优化get时性能,不会被阻塞。


class RWDictionary {
    private final Map m = new TreeMap<>();
    private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
    private final Lock r = rwl.readLock();
    private final Lock w = rwl.writeLock();

    public Data get(String key) {
        r.lock();
        try {
            return m.get(key);
        } finally {
            r.unlock();
        }
    }

    public List allKeys() {
        r.lock();
        try {
            return new ArrayList<>(m.keySet());
        } finally {
            r.unlock();
        }
    }

    public Data put(String key, Data value) 

你可能感兴趣的:(java,开发语言,jvm)