ReadWriteLock读写锁

8/31/2021 多线程

# ReadWriteLock读写锁简单介绍✨

ReentrantLock(可重入锁) 保证了只有一个线程可以执行临界区代码,在任何时刻,只允许一个线程修改数据。但是有些时候,我们希望允许多个线程同时读某个数据,但只有一个线程在写,其他线程就必须等待

使用 ReadWriteLock 可以解决这个问题

  • 只允许一个线程写入(其他线程既不能写入也不能读取);
  • 没有写入时,多个线程允许同时读(提高性能)。

# 读写锁🎐

public class Counter {
    private final ReadWriteLock rwlock = new ReentrantReadWriteLock();
    private final Lock rlock = rwlock.readLock();
    private final Lock wlock = rwlock.writeLock();
    private int[] counts = new int[10];

    public void inc(int index) {
        wlock.lock(); // 加写锁
        try {
            counts[index] += 1;
        } finally {
            wlock.unlock(); // 释放写锁
        }
    }

    public int[] get() {
        rlock.lock(); // 加读锁
        try {
            return Arrays.copyOf(counts, counts.length);
        } finally {
            rlock.unlock(); // 释放读锁
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

把读写操作分别用读锁和写锁来加锁,在读取时,多个线程可以同时获得读锁,这样就大大提高了并发读的执行效率。

使用ReadWriteLock时,适用条件是同一个数据,有大量线程读取,但仅有少数线程修改。

例如,一个论坛的帖子,回复可以看做写入操作,它是不频繁的,但是,浏览可以看做读取操作,是非常频繁的,这种情况就可以使用ReadWriteLock。

# 小结⭕

使用ReadWriteLock可以提高读取效率:

  • ReadWriteLock只允许一个线程写入;

  • ReadWriteLock允许多个线程在没有写入时同时读取;

  • ReadWriteLock适合读多写少的场景。