Java线程之共享锁和排他锁及ReentrantReadWriteLock的使用

11 篇文章 0 订阅

排他锁

  • 排他锁:独享锁、独占锁。一个线程获取锁,其他线程等待。也就是:synchronized

共享锁

  • 共享锁:在锁中,有个叫读锁。读锁也就是共享锁。也就是说多个线程可以同时获取读锁。有了读锁,必然有写锁。写锁的话只能一个线程写,多个线程同时写肯定会有问题,是不是。

我们来总结一下:

  • 多个线程可以同时读,只能一个线程写操作。

我就来代码实现一把,哈哈哈

案例:线程1线程2 读数据(是不是同时读)线程3线程4是写数据(不能同时写,只能排队写)
code
/**
 * 功能描述:
 *案例:线程1线程2 读数据(是不是同时读)线程3线程4是写数据(不能同时写,只能排队写)
 * @author Songxianyang
 * @date 2022-06-11 21:56
 */
public class ReadWriteLock11Day {
    /**
     * 主锁
     */
    private static ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    
    /**
     * 读锁
     */
    private static ReentrantReadWriteLock.ReadLock readLock = readWriteLock.readLock();
    
    /**
     * 写锁
     */
    private static ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock();
    
    public static void main(String[] args) {
        ReadWriteLock11Day lock11Day = new ReadWriteLock11Day();
        new Thread(() -> {
            lock11Day. read();
        }, "线程1").start();
        new Thread(() -> {
            lock11Day. read();
        }, "线程2").start();
        new Thread(() -> {
            lock11Day. write();
        }, "线程3").start();
        new Thread(() -> {
            lock11Day. write();
        }, "线程4").start();
    }
    
    private void read() {
        readLock.lock();
        try {
            System.out.println("当前:"+Thread.currentThread().getName()+"正在执行(读锁)");
        } finally {
            readLock.unlock();
        }
    }
    
    private void write() {
        writeLock.lock();
        try {
            Thread.sleep(1000);
            System.out.println("当前:"+Thread.currentThread().getName()+"正在执行(写锁)");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            writeLock.unlock();
        }
    }
}

执行效果

image.png

总结:读锁同时读。写锁排队写。

读写锁中的 公平与非公平

  • 不公平的的想看不就是 插队现象。哈哈 没毛病

说一线非公平插队

看一下源码的构造方法:

image.png
检测头节点是否是写,如果是写 必须去排队

image.png

代码:

/**
 * 功能描述:
 *案例:线程1线程2 读数据(是不是同时读)线程3线程4是写数据(不能同时写,只能排队写)
 * @author Songxianyang
 * @date 2022-06-11 21:56
 */
public class ReadWriteLock11Day {
    /**
     * 主锁
     */
    private static ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(false);
    
    /**
     * 读锁
     */
    private static ReentrantReadWriteLock.ReadLock readLock = readWriteLock.readLock();
    
    /**
     * 写锁
     */
    private static ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock();
    
    public static void main(String[] args) {
        ReadWriteLock11Day lock11Day = new ReadWriteLock11Day();
        new Thread(() -> {
            lock11Day. read();
        }, "线程1").start();
        new Thread(() -> {
            lock11Day. read();
        }, "线程2").start();
        new Thread(() -> {
            lock11Day. write();
        }, "线程3").start();
        new Thread(() -> {
            lock11Day. write();
        }, "线程4").start();
        new Thread(() -> {
            lock11Day.read();
        }, "线程5").start();
    }
    
    private void read() {
        readLock.lock();
        try {
            System.out.println("当前:"+Thread.currentThread().getName()+"正在执行(读锁)");
        } finally {
            readLock.unlock();
        }
    }
    
    private void write() {
        writeLock.lock();
        try {
            Thread.sleep(1000);
            System.out.println("当前:"+Thread.currentThread().getName()+"正在执行(写锁)");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            writeLock.unlock();
        }
    }
}
效果图

image.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SteveCode.

永远年轻,永远热泪盈眶

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值