【并发编程篇】读锁readLock()和写锁writeLock()-LMLPHP
readLock()和writeLock()都是ReadWriteLock接口中定义的方法,用于获取读锁和写锁。

readLock()方法返回一个读锁,允许同时获取该锁,以进行并发读取操作。如果当前已有一个写锁或其他线程正在请求写锁,则读锁会被阻塞,直到所有写锁请求完成并释放锁为止。读锁和写锁之间是互斥的。

writeLock()方法返回一个写锁,只允许获取该锁,以进行写入操作。如果当前已有一个读锁或其他线程正在请求读锁,则写锁会被阻塞,直到所有读锁请求完成并释放锁为止。写锁是独占的,同一时间只能有一个线程持有写锁。

在使用读写锁时,应该根据具体的业务场景和需求选择适当的锁类型。如果共享资源的读取操作远远超过写入操作,那么使用读写锁可以提高系统的并发性能。如果写入操作非常频繁,那么使用读写锁可能会导致读取操作的性能下降,因为读取线程需要等待写入线程释放写锁。此外,读写锁也需要消耗额外的系统资源,因此应该避免不必要的锁竞争。

🛸情景引入

我们先看下面这段代码
【并发编程篇】读锁readLock()和写锁writeLock()-LMLPHP

本来应该是1写入,然后1写入完全
但是现在1写入后,紧跟着的是3写入
这明显是错误的

⭐解决问题

下面我们来加上锁,解决问题

package org.Test6;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ReadWriteLockDemo {
    public static void main(String[] args) {
        MyCacheLock myCache = new MyCacheLock();

        //写入
        for(int i=1;i<=5;i++){
            final int temp=i;
            new Thread(()->{
                myCache.put(temp+"",temp+"");
            },String.valueOf(i)).start();
        }

        //读取
        for(int i=1;i<=5;i++){
            final int temp=i;
            new Thread(()->{
                myCache.get(temp+"");
            },String.valueOf(i)).start();
        }
    }
}

//自定义缓存
class MyCacheLock{
    private volatile Map<String,Object> map = new HashMap<>();
    private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

    //存 写 写入的时候
    // 只希望只有一个线程去写
    public void put(String key,Object value){
        readWriteLock.writeLock().lock();  //加锁

        try {
            System.out.println(Thread.currentThread().getName()+"写入"+key);
            map.put("key","value");
            System.out.println(Thread.currentThread().getName()+"写入结束");
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            readWriteLock.writeLock().unlock();  //解锁
        }


    }

    //取 读
    //读的时候,所有人都可以读
    public void get(String key){
        readWriteLock.readLock().lock(); //加锁

        try {
            System.out.println(Thread.currentThread().getName()+"读取"+key);
            Object o=map.get("key");
            System.out.println(Thread.currentThread().getName()+"读取结束");
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            readWriteLock.readLock().unlock(); //解锁
        }


    }
}

【并发编程篇】读锁readLock()和写锁writeLock()-LMLPHP

独占锁(写锁):一次只能被一个线程占有
共享锁(读锁):多个线程可以同时占有

【并发编程篇】读锁readLock()和写锁writeLock()-LMLPHP

12-26 07:41