java并发(5)ReentrantReadWriteLock读写锁

本文详细解析了读写锁的工作原理,对比了synchronized锁,阐述了读写锁如何实现多读不互斥、读写互斥的特性,以及读写锁的重入、降级等高级特性,并通过示例代码展示了读写锁的具体应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

学习:https://blog.youkuaiyun.com/u012506661/article/details/53157004

          

1,synchronized的锁是不分读写的,假设一个对象有读方法还有写方法,我们希望读方法和写方法能不同线程访问,所以读写锁解决了这个问题,当写操作时,其他线程无法读取或者写数据,而读操作时,其他线程虽然无法写数据,但是可以读数据,也就是说,读可以多线程共享。

2,读写锁:分为读锁和写锁,多读不互斥,读写互斥,也就是说写的时候只能一个人写并且不能读,读可以多人同时读但不能写。总之读就上读锁,写就上写锁

3,线程进入读锁前提:没有其他线程写锁,没有写的请求或者有写请求,但调用线程和持有线程是同一个。

    线程进入写锁前提:没有其他线程读,没有其他线程写

4,特性:

a,重入方面其内部的写锁可以获取读锁,但反过来不行。

b,写锁可以降级读锁,顺序是先写锁获得读锁,然后释放写锁,这个时候该线程保持读锁的拥有,反过来不行。

c,读锁可以被多个线程持有并且排斥写锁,而写锁则是完全互斥。

d,不管读还是写,都支持中断。

e,写支持Condition并且语义与ReentrantLock一样,但是读锁不能用Condition,会抛出异常。

5,使用

package com.study.webapp.lock;

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

public class ReentrantReadWriterLockTest {

    public static void main(String[] args) {
        ReentrantReadWriterLockTest t = new ReentrantReadWriterLockTest();
        ReentrantReadWriterLockTest.model m = t.new model();
        for (int i = 0; i < 3; i++) {
            new Thread() {
                public void run() {
                    m.get();
                }
            }.start();
        }

        for (int i = 0; i < 3; i++) {
            new Thread() {
                public void run() {
                    m.put(new Random().nextInt(10000));
                }
            }.start();
        }
    }

    class model {
        private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
        private Object data = null;

        public void get() {
            lock.readLock().lock();
            System.out.println(Thread.currentThread().getName() + ">>读锁");
            try {
                Thread.sleep((long) (Math.random() * 1000));
            } catch (Exception e) {

            }
            System.out.println(Thread.currentThread().getName() + ">>读锁>>" + data);
            lock.readLock().unlock();
        }

        public void put(Object data) {
            lock.writeLock().lock();
            System.out.println(Thread.currentThread().getName() + ">>>>写锁");
            try {
                Thread.sleep((long) (Math.random() * 1000));
            } catch (Exception e) {

            }
            this.data = data;
            System.out.println(Thread.currentThread().getName() + ">>写锁>>" + data);
            lock.writeLock().unlock();
        }
    }
}
 

5.2 锁的降级

package com.study.webapp.lock;

import java.util.concurrent.locks.ReentrantReadWriteLock;

public class WriteToRead {

    ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    public void CachedData() {
        lock.readLock().lock();
        // 做某些操作
        System.out.println(Thread.currentThread().getName());
        // 获取写锁前一定要先释放读锁
        lock.readLock().unlock();
        lock.writeLock().lock();
        System.out.println(Thread.currentThread().getName());
        // 在释放写锁前可以获取读锁
        lock.readLock().lock();
        lock.writeLock().unlock();
        // 释放完写锁再释放读锁
        lock.readLock().unlock();
    }

}

6,源码分析

http://cmsblogs.com/?p=2213

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值