读写锁

读写锁的特性

读读是共享的。读写,写写是互斥的。

1.读读互斥例子

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

public class ReentrantReadWriteLockDemo {

    private int i = 0;
    private int j = 0;

    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    Lock readLock = lock.readLock();
    Lock writeLock = lock.writeLock();

    public void out(){
        readLock.lock();
        System.out.println(Thread.currentThread().getName()+",(i="+i+"j="+j+")");
        readLock.unlock();
    }

    public void increase(){
        writeLock.lock();
        try {
            i++;
            Thread.sleep(500l);
            j++;
        }catch (InterruptedException e){
            e.printStackTrace();
        }finally {
            writeLock.unlock();
        }

    }

    public static void main(String[] args) {
        ReentrantReadWriteLockDemo reentrantReadWriteLockDemo = new ReentrantReadWriteLockDemo();


        new Thread(()->{
            reentrantReadWriteLockDemo.increase();
        },"写线程1").start();

        new Thread(()->{
            reentrantReadWriteLockDemo.increase();
        },"写线程2").start();
    }
}

在increase()方法打断点,进行多线程debug,当写线程1获取到写锁时,写线程2尝试去获取锁,显示无法获取锁,进入等待状态,由此说明,写写是互斥的。

2.读写互斥,我们将main方法如下修改一下,再debug。

 public static void main(String[] args) {
        ReentrantReadWriteLockDemo reentrantReadWriteLockDemo = new ReentrantReadWriteLockDemo();
        
        new Thread(()->{
            reentrantReadWriteLockDemo.increase();
        },"写线程1").start();

        new Thread(()->{
            reentrantReadWriteLockDemo.out();
        },"读线程2").start();
    }

在increase()和out()方法上打上断点,进行多线程debug,如下写线程1和读线程2正常启动

当写线程1获得锁时,读线程2尝试去获得锁,读线程2拿不到锁,进入等待状态(反之先让读线程2先获取锁时,再让写线程1尝试获得锁的也是一样的,写线程会获取失败进入等待状态,这里就不一一展示了),说明读写也是互斥的。 

 

3.读读不互斥,我们将mian方法再改一下

public static void main(String[] args) {
        ReentrantReadWriteLockDemo reentrantReadWriteLockDemo = new ReentrantReadWriteLockDemo();

        new Thread(()->{
            reentrantReadWriteLockDemo.out();
        },"读线程1").start();

        new Thread(()->{
            reentrantReadWriteLockDemo.out();
        },"读线程2").start();
    }

debug结果如下,在读线程1获得读锁时,读线程2仍然可以获取到读锁,说明读读是不互斥的 

4.锁降级

    写锁程序获得写入锁后可以获得读取锁,然后释放写入锁,这样就从写入锁变成读写锁,从而实现读写锁的降级。

注意

    锁降级之后,血锁并不会直接降成读锁,不会随着读锁的释放而释放,因此需要显示地释放写锁

简单例子

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

public class LockDegrade {

    public static void main(String[] args) {
        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
        Lock readLock = lock.readLock();
        Lock writeLock = lock.writeLock();

        writeLock.lock();
        readLock.lock();
        writeLock.unlock();
        readLock.unlock();

        System.out.println("运行结束");

    }
}

   运行结果如下,主线程获得写锁之后可以获得读锁,并且写锁释放后,后面的释放读锁代码也正常运行,说明读锁在写锁释放后仍然能用。

锁降级的应用

数据比较敏感,需要在对数据修改后获取到数据 修改后的值,做其他操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值