Skip to main content

读写锁ReadWriteLock

huhxAbout 1 minjavaConcurrency-ToolkitConcurrency

使用

public class ReadWriteLockMain {
    private static int value = 0;

    static void read(Lock lock) {
        try {
            lock.lock();
            TimeUnit.SECONDS.sleep(1);
            System.out.printf("Finish read %d, time: %s\n", value, LocalDateTime.now());
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            lock.unlock();
        }
    }

    static void write(Lock lock, int newVal) {
        try {
            lock.lock();
            TimeUnit.SECONDS.sleep(1);
            value = newVal;
            System.out.printf("Finish write %d, time: %s\n", newVal, LocalDateTime.now());
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            lock.unlock();
        }
    }

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

        for (int i = 0; i < 3; i++) new Thread(() -> read(lock.readLock())).start();
        for (int i = 0; i < 2; i++) new Thread(() -> write(lock.writeLock(), new Random().nextInt(12))).start();
    }
}

输出结果是:

Finish read 0, time: 2023-09-07T10:42:19.531316
Finish read 0, time: 2023-09-07T10:42:19.531389
Finish read 0, time: 2023-09-07T10:42:19.531318
Finish write 8, time: 2023-09-07T10:42:20.549605
Finish write 9, time: 2023-09-07T10:42:21.553636

如果修改上述的main方法如下:

public static void main(String[] args) {
    var lock = new ReentrantLock();
    for (int i = 0; i < 3; i++) new Thread(() -> read(lock)).start();
    for (int i = 0; i < 2; i++) new Thread(() -> write(lock, new Random().nextInt(12))).start();
}

那么此次的输出结果:

Finish read 0, time: 2023-09-07T10:43:06.426840
Finish read 0, time: 2023-09-07T10:43:07.442590
Finish read 0, time: 2023-09-07T10:43:08.448698
Finish write 6, time: 2023-09-07T10:43:09.453418
Finish write 7, time: 2023-09-07T10:43:10.457287

分析

FAQ

总结

ReadWriteLock可以提高读取效率,适合于读多写少的场景

  • ReadWriteLock只允许一个线程写入,在写入时线程不能读取(线程安全)
  • ReadWriteLock在没有写入的时候,多个线程是可以同时读取(提高性能)

参考