使用 ReadWriteLock 实现读写锁

x33g5p2x  于2022-03-19 转载在 其他  
字(2.2k)|赞(0)|评价(0)|浏览(221)

一 点睛

为了更好地解决多个线程读写带来的并发问题,JUC 还提供了专门的读写锁 ReadWriteLock,可以分别用于对读或写操作进行加锁,ReadWriteLock 在 JDK 中的源码如下所示。
public interface ReadWriteLock {

Lock readLock();

Lock writeLock();

}

源码中 readLock 和 writeLock 的含义如下:

1 readLock():读锁。加了读锁的资源,可在没有写锁的时候被多个线程共享。换句话说,如果 t1 线程已经获取了读锁,那么此时存在以下状态。

a 如果 t2 线程要申请写锁,那 t2 会一直等待 t1 释放读锁。

b 如果 t2 线程要申请读锁,则 t2 可以直接访问读锁,也就是说 t1 和 t2 可以共享资源,就和没加锁的效果一样。

2 writeLock():写锁,是独占锁。加了写锁的资源,不能再被其他线程读写。换句话说,如果 t1 已经获取了写锁,那么此时无论线程 t2 要申请写锁或者读锁,都必须等待 t1 释放写锁。

二 代码

package concurrent;

import java.util.concurrent.locks.ReentrantReadWriteLock;

public class TestReadWriteLock {
    // 读写锁
    private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

    public static void main(String[] args) {
        TestReadWriteLock test = new TestReadWriteLock();
        // t1线程
        new Thread(() -> {
            // 读操作
            test.myRead(Thread.currentThread());
            // 写操作
            test.myWrite(Thread.currentThread());
        }, "t1").start();

        // t2线程
        new Thread(() -> {
            // 读操作
            test.myRead(Thread.currentThread());
            // 写操作
            test.myWrite(Thread.currentThread());
        }, "t2").start();
    }

    // 用读锁来锁定读操作
    public void myRead(Thread thread) {
        rwl.readLock().lock();
        try {
            for (int i = 0; i < 20; i++) {
                System.out.println(thread.getName() + "正在进行读操作");
            }
            System.out.println(thread.getName() + "===读操作完毕===");
        } finally {
            rwl.readLock().unlock();
        }
    }

    // 用写锁来锁定写操作
    public void myWrite(Thread thread) {
        rwl.writeLock().lock();
        try {
            for (int i = 0; i < 20; i++) {
                System.out.println(thread.getName() + "正在进行写操作");
            }
            System.out.println(thread.getName() + "===写操作完毕===");
        } finally {
            rwl.writeLock().unlock();
        }
    }
}

三 测试

t1正在进行读操作
t1正在进行读操作
t1正在进行读操作
t1正在进行读操作
t1正在进行读操作
t1正在进行读操作
t1正在进行读操作
t1正在进行读操作
t1正在进行读操作
t2正在进行读操作
t2正在进行读操作
t2正在进行读操作
t2正在进行读操作
t2正在进行读操作
t2正在进行读操作
t2正在进行读操作
t2正在进行读操作
t2正在进行读操作
t2正在进行读操作
t2正在进行读操作
t2正在进行读操作
t2正在进行读操作
t2正在进行读操作
t2正在进行读操作
t2正在进行读操作
t2正在进行读操作
t2正在进行读操作
t1正在进行读操作
t1正在进行读操作
t1正在进行读操作
t1正在进行读操作
t1正在进行读操作
t1正在进行读操作
t1正在进行读操作
t1正在进行读操作
t1正在进行读操作
t1正在进行读操作
t1正在进行读操作
t2正在进行读操作
t2正在进行读操作
t2===读操作完毕===
t1===读操作完毕===
t1正在进行写操作
t1正在进行写操作
t1正在进行写操作
t1正在进行写操作
t1正在进行写操作
t1正在进行写操作
t1正在进行写操作
t1正在进行写操作
t1正在进行写操作
t1正在进行写操作
t1正在进行写操作
t1正在进行写操作
t1正在进行写操作
t1正在进行写操作
t1正在进行写操作
t1正在进行写操作
t1正在进行写操作
t1正在进行写操作
t1正在进行写操作
t1正在进行写操作
t1===写操作完毕===
t2正在进行写操作
t2正在进行写操作
t2正在进行写操作
t2正在进行写操作
t2正在进行写操作
t2正在进行写操作
t2正在进行写操作
t2正在进行写操作
t2正在进行写操作
t2正在进行写操作
t2正在进行写操作
t2正在进行写操作
t2正在进行写操作
t2正在进行写操作
t2正在进行写操作
t2正在进行写操作
t2正在进行写操作
t2正在进行写操作
t2正在进行写操作
t2正在进行写操作
t2===写操作完毕===

相关文章

微信公众号

最新文章

更多