java多线程---读写锁ReadWriteLock

Posted Ch1nYK

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java多线程---读写锁ReadWriteLock相关的知识,希望对你有一定的参考价值。

public interface ReadWriteLock

ReadWriteLock 维护了一对相关的锁,一个用于只读操作,另一个用于写入操作。只要没有 writer,读取锁可以由多个 reader 线程同时保持。写入锁是独占的。
public abstract interface ReadWriteLock
{
  public abstract Lock readLock();
  
  public abstract Lock writeLock();
}

访问约束

read write
read 非阻塞 阻塞
write 阻塞 阻塞

ReentrantReadWriteLock诞生于J·U·C。此后,国人一般称它为读写锁。人如其名,人如其名,她就是一个可重入锁,同时她还是一个读、写锁。
ReentrantReadWriteLock实现了ReadWriteLock和Serializable,同时ReadWriteLock跟Lock也没有继承关系。
ReentrantReadWriteLock跟ReentrantLock只有朋友关系,她们都是一个可重入锁。

eg:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ReadWriteLockTest implements Runnable{
    private static ReentrantLock rl = new ReentrantLock();
    private static ReentrantReadWriteLock readwriteLock = new ReentrantReadWriteLock();
    private static Lock readLock = readwriteLock.readLock();
    private static Lock writeLock = readwriteLock.writeLock();
    
    public void handleRead(Lock lock) throws InterruptedException{
        try{
            lock.lock();
            Thread.sleep(1000);
            System.out.println(Thread.currentThread().getName() + "   获得了读锁, 时间为" + 
                    System.currentTimeMillis());
        }finally{
            lock.unlock();
        }
    }
    
    public void handleWrite(Lock lock) throws InterruptedException{
        try{
            lock.lock();
            Thread.sleep(1000);
            System.out.println(Thread.currentThread().getName() + "  获得了写锁, 时间为" + 
                    System.currentTimeMillis());
        }finally{
            lock.unlock();
        }
    }
    
    @Override
    public void run() {
        
        
    }
    
    public static void main(String[] args) {
        final ReadWriteLockTest rwlt = new ReadWriteLockTest();
        Runnable read = new Runnable(){
            public void run(){
                try {
                    rwlt.handleRead(readLock);
                    //rwlt.handleRead(rl);      //假如使用普通的重入锁,读写之间相互等待
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        Runnable write = new Runnable(){
            public void run(){
                try{
                    rwlt.handleWrite(writeLock);
                    //rwlt.handleWrite(rl);     //假如使用普通的重入锁,读写之间相互等待
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        Thread[] readThread = new Thread[10];
        for (int i = 0; i < 10; i++) {
            readThread[i] = new Thread(read);
            readThread[i].start();
        }
        Thread[] writeThread = new Thread[5];
        for (int i = 0; i < 5; i++) {
            writeThread[i] = new Thread(write);
            writeThread[i].start();
        }
    }

    
}

在JDK1.8之前,ReentrantReadWriteLock是ReadWriteLock的唯一实现,它由读、写锁组成,读是共享锁、写是独占锁,且读写互斥,它使用的依然是悲观的锁策略.如果有大量的读线程,他也有可能引起写线程的饥饿。JDK1.8,引进一种新的机制(StampedLock),StampedLock则提供了一种乐观的读策略,这种乐观策略的锁非常类似于无锁的操作,使得乐观锁完全不会阻塞写线程。



以上是关于java多线程---读写锁ReadWriteLock的主要内容,如果未能解决你的问题,请参考以下文章

java多线程---读写锁ReadWriteLock

Springboot Java多线程操作本地文件,加读写锁,阻塞的线程等待运行中的线程执行完再查询并写入

java多线程ReadWriteLock读写锁

“全栈2019”Java多线程第四十二章:获取线程与读写锁的保持数

Java多线程13:读写锁和两种同步方式的对比

(多线程与并发)面试题03--java中读写锁ReadWriteLock