ReadWriteLock读写锁

ReadWriteLock管理的是一组锁,一个是读锁,一个是写锁。

当前两个锁是同时使用的。

其实很多人能理解写锁,因为写锁的话,写如果并发的话,那就出现脏数据。

不过为什么会存在读锁?读为什么要锁?

其实数据有完整性。

比如:

public class Man {


    public String name = "0";
    public String age = "18";


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
}
public class MutilThread {
    private static Man man = new Man();
    public static ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    private static Lock writeLock = lock.writeLock();
    private static Lock readLock = lock.readLock();
    public static void main(String[] args)   {
        ExecutorService service = Executors.newFixedThreadPool(20);
        service.execute(new Runnable() {
            @Override
            public void run() {
                read();
            }
        });
        for (int i = 0; i < 30; i++) {
            service.execute(new Runnable() {
                @Override
                public void run() {
                    write();
                }
            });
        }
    }

    public static  void read(){
        while (true){
            readLock.lock();
            Thread thread = Thread.currentThread();
            System.out.println("thread name "+thread.getName()+",man name  = " + man.name+"  age : "+ man.age);
            if (man.name.equals( "余")&&man.age.equals("22")){
                            System.out.println("1+thread name "+thread.getName()+",man name  = " + man.name+"  age : "+ man.age);
            }
            if (man.name.equals( "小明")&&man.age.equals("18")){
                System.out.println("2+thread name "+thread.getName()+",man name  = " + man.name+"  age : "+ man.age);
            }
            readLock.unlock();
        }
    }
    public static void write() {
        while (true) {
            writeLock.lock();
            Thread thread = Thread.currentThread();
            if (thread.getId()%2!=0){
                man.name = "余";
                man.age = "18";
//                System.out.println("thread name "+thread.getName()+",man name  = " + man.name+"  age : "+ man.age);
            }
            if (thread.getId()%2!=1){
                man.name = "小明";
                man.age = "22";
//                System.out.println("thread name "+thread.getName()+",man name  = " + man.name+"  age : "+ man.age);
            }
            writeLock.unlock();
        }
    }
}

 

存在两个成员变量,如果我们读的时候,如果只是写加了锁,读没有加读锁的话,你会发现读的时候没有读完整,会出现读的脏数据。比如出现余 22岁的这个情况是不应该出现的。所以读锁是保证读取的数据的完整性的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的 Java 代码实现 ReadWriteLock 读写锁: ```java public class ReadWriteLock { private int readers = 0; private int writers = 0; private int writeRequests = 0; public synchronized void lockRead() throws InterruptedException { while (writers > 0 || writeRequests > 0) { wait(); } readers++; } public synchronized void unlockRead() { readers--; notifyAll(); } public synchronized void lockWrite() throws InterruptedException { writeRequests++; while (readers > 0 || writers > 0) { wait(); } writeRequests--; writers++; } public synchronized void unlockWrite() { writers--; notifyAll(); } } ``` 在这个实现中,我们使用了几个变量来跟踪读写锁的状态: - `readers`:当前持有读锁的线程数。 - `writers`:当前持有写锁的线程数。 - `writeRequests`:当前等待获取写锁的线程数。 在 `lockRead` 方法中,如果有线程持有写锁或者有线程在等待获取写锁,我们会让当前线程等待,直到可以获取读锁为止。如果可以获取读锁,我们将 `readers` 计数器加一。 在 `unlockRead` 方法中,我们将 `readers` 计数器减一,并且唤醒所有等待的线程。 在 `lockWrite` 方法中,我们将 `writeRequests` 计数器加一,然后检查是否有线程持有读锁或者写锁。如果有,我们会让当前线程等待,直到可以获取写锁为止。如果可以获取写锁,我们将 `writeRequests` 计数器减一,并且将 `writers` 计数器加一。 在 `unlockWrite` 方法中,我们将 `writers` 计数器减一,并且唤醒所有等待的线程。 这样,我们就实现了一个简单的 ReadWriteLock 读写锁。在读锁中,多个线程可以并发读取共享资源,而在写锁中,只有一个线程可以写入共享资源,其他线程会被阻塞。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值