侧边栏壁纸
博主头像
DJ's Blog博主等级

行动起来,活在当下

  • 累计撰写 133 篇文章
  • 累计创建 51 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

【Java】ReentrantReadWriteLock

Administrator
2022-04-05 / 0 评论 / 0 点赞 / 57 阅读 / 3537 字

【Java】ReadWriteLock & ReentrantReadWriteLock

ReadWriteLock

ReadWriteLock也是一个接口,在它里面只定义了两个方法:

public interface ReadWriteLock {
	Lock readLock();
	Lock writeLock();
}

readLock()用来获取读锁,writeLock()用来获取写锁。也就是说将文件的读写操作分开,分成2个锁来分配给线程,从而使得多个线程可以同时进行读操作。

ReentrantReadWriteLock

ReentrantReadWriteLockReadWriteLock接口的实现,里面提供了很多丰富的方法,不过最主要的有两个方法:readLock()writeLock()用来获取读锁和写锁。

代码示例

  • 假如有多个线程要同时进行读操作的话,先看一下synchronized达到的效果
public class SynchronizedReadWriteTest implements Runnable {
    @Override
    public synchronized void run() {
        Thread currentThread = Thread.currentThread();
        long start = System.currentTimeMillis();
        int i = 0;
        while (System.currentTimeMillis() - start <= 1) {
            i++;
            if (i % 4 == 0) {
                System.out.println(currentThread.getName() + "正在进行写操作");
            } else {
                System.out.println(currentThread.getName() + "正在进行读操作");
            }
        }
        System.out.println(currentThread.getName() + "读写操作完毕");
    }
    public static void main(String[] args) {
        SynchronizedReadWriteTest test = new SynchronizedReadWriteTest();
        Thread thread1 = new Thread(test, "thread1");
        Thread thread2 = new Thread(test, "thread2");
        thread1.start();
        thread2.start();
    }
}

一个线程又要读又要写,用synchronized来实现的话,读写操作都只能锁住后一个线程一个线程地进行

  • 改成用读写锁的话
public class ReentrantReadWriteLockTest implements Runnable {
    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    public void get(Thread thread) {
        lock.readLock().lock();
        try {
            long start = System.currentTimeMillis();
            while (System.currentTimeMillis() - start <= 1) {
                System.out.println(thread.getName() + "正在进行读操作");
            }
            System.out.println(thread.getName() + "读操作完毕");
        } finally {
            lock.readLock().unlock();
        }
    }
    public void write(Thread thread) {
        lock.writeLock().lock();
        try {
            long start = System.currentTimeMillis();

            while (System.currentTimeMillis() - start <= 1) {
                System.out.println(thread.getName() + "正在进行写操作");
            }
            System.out.println(thread.getName() + "写操作完毕");
        } finally {
            lock.writeLock().unlock();
        }
    }
    @Override
    public void run() {
        Thread currentThread = Thread.currentThread();
        get(currentThread);
        write(currentThread);
    }
    public static void main(String[] args) {
        ReentrantReadWriteLockTest test = new ReentrantReadWriteLockTest();
        Thread thread1 = new Thread(test, "thread1");
        Thread thread2 = new Thread(test, "thread2");
        thread1.start();
        thread2.start();
    }
}

如果有一个线程已经占用了读锁,则此时其他线程如果要申请写锁,则申请写锁的线程会一直等待释放读锁。但是读操作还是可以继续进行。
如果有一个线程已经占用了写锁,则此时其他线程如果申请写锁或者读锁,则申请的线程会一直等待释放写锁。

0

评论区