ReentrantReadWriteLock()读写锁实战

读写锁是两把锁,声明的话是一个对象,锁也是锁一个方法。但是分读锁,和写锁。

写锁与写锁之间是不互斥的,可以有多个线程同时读;

但是写锁是互斥的,同一时间只能有一个线程写;

有一个特点:

当有线程在写是,是不可以读的、要等写锁被释放后,才可以读。

public class TestReentrantReadWriteLock {
    private static final ReadWriteLock lock = new ReentrantReadWriteLock();
    static ExecutorService es = Executors.newFixedThreadPool(5);

    public static void main(String[] args) {
        String name1 = "小明";
        String name2 = "小红";

        es.submit(new Runnable() {
            @Override
            public void run() {
                writeOnlyOne(name1);
            }
        });
        es.submit(new Runnable() {
            @Override
            public void run() {
                readOnlyOne(name1);
            }
        });
        es.submit(new Runnable() {
            @Override
            public void run() {
                readOnlyOne(name2);
            }
        });
        es.submit(new Runnable() {
            @Override
            public void run() {
                writeOnlyOne(name1);
            }
        });
        es.submit(new Runnable() {
            @Override
            public void run() {
                writeOnlyOne(name2);
            }
        });
        es.shutdown();
        es.shutdown();

        //    结果:
        //    小明开始写2022-01-27 04:22:25
        //小明写完了2022-01-27 04:22:30
        //小明开始读2022-01-27 04:22:30
        //小红开始读2022-01-27 04:22:30
        //小明读完了2022-01-27 04:22:32
        //小红读完了2022-01-27 04:22:32
        //小明开始写2022-01-27 04:22:32
        //小明写完了2022-01-27 04:22:37
        //小红开始写2022-01-27 04:22:37
        //小红写完了2022-01-27 04:22:42
    }

    public static void readOnlyOne(String name) {
        try {
            lock.readLock().lockInterruptibly();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        System.out.println(String.format("%s开始读", name) + getNow());
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(String.format("%s读完了", name) + getNow());
        lock.readLock().unlock();
    }

    public static void writeOnlyOne(String name) {
        try {
            lock.writeLock().lockInterruptibly();
        } catch (InterruptedException e) {
            System.out.println(e.getMessage());
        }
        System.out.println(String.format("%s开始写", name) + getNow());
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(String.format("%s写完了", name) + getNow());
        lock.writeLock().unlock();
    }

    public static String getNow() {
        Date date = new Date(System.currentTimeMillis());
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        return dateFormat.format(date);
    }
}

看下结果:

//    结果:
//    小明开始写2022-01-27 04:22:25
//小明写完了2022-01-27 04:22:30
//小明开始读2022-01-27 04:22:30
//小红开始读2022-01-27 04:22:30
//小明读完了2022-01-27 04:22:32
//小红读完了2022-01-27 04:22:32
//小明开始写2022-01-27 04:22:32
//小明写完了2022-01-27 04:22:37
//小红开始写2022-01-27 04:22:37
//小红写完了2022-01-27 04:22:42

小明开始写的时候

小明和小红都不能读

5秒后小明写完了

小明和小红都可以读,而且是同时读

此时注意

小明和小红在读期间

小明是不能写的

2秒后

小明小红读完了

小明可以写了

小明开始写

5秒后

小红才能开始写

5秒后

小红写完了

总结一下上面漏的一点:

就是读锁被抢后,写锁是不能获取的

在读期间,不能写

在写期间,不能读

读锁不互斥

写锁互斥

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值