读写锁

本文介绍了读写锁的基本概念及其在Java中的实现方式。通过对比排他锁(如ReentrantLock和synchronized),突出了读写锁的特点:允许多个读线程同时访问资源,但在写操作时会阻塞所有其他读写请求。并通过一个具体的Java实现示例,展示了如何正确地使用读写锁来提高多线程应用的并发性能。

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

1.ReentrantLock、Synchronized都是排他锁,这些锁在同一时刻只允许一个线程进行访问,而读写锁在同一时刻允许多个读线程访问,但是在写线程访问时,所有的读线程和其他写线程均被阻塞。

1.由于读和读之间并不对数据的完整性造成破坏,所以读写锁允许多个线程同时读,但是读写操作、写写操作之间仍然要相互等待和持有锁的。而重入锁在读和读互斥等待浪费了时间。

1)读写锁使用方法:

                    ReadWriterLock rwlock = new ReentranReadWriterLock();

                    rwlock.writeLock().lock();     //获得写入操作的锁,并上锁

                    //写入操作执行

                    rwlock.writeLock().unlock();   //获得写入操作的锁,并解锁

                    rwlock.readLock().lock();        //获取读取操作的锁,并上锁

                    //读取操作执行

                    rwlock.readLock().unlock();     //获取读取操作的锁,并解锁

博客https://blog.youkuaiyun.com/lzm1340458776/article/details/27964243中例子看到读写锁运行效果。

class ReadWrite {  
    //共享数据,只能一个线程写数据,可以多个线程读数据   
    private Object data = null;  
    //创建一个读写锁   
    ReadWriteLock rwlock = new ReentrantReadWriteLock();  
    Lock r = rwlock.readLock();			//读锁
    Lock w = rwlock.writeLock();		//写锁
    
    public void get() {  
        r.lock();  		//读上锁
        try {  
            System.out.println(Thread.currentThread().getName() + "**准备读数据!");  
            Thread.sleep((long) (Math.random() * 1000));  			//模拟读操作
            System.out.println(Thread.currentThread().getName() + "---------读出的数据为 :" + data);  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        } finally {  
        	r.unlock();
        }  
  
    }  
  
    public void put(Object data) {  
        w.lock();  	//写上锁
        try {  
            System.out.println(Thread.currentThread().getName() + " +++++++准备写数据!");    
            Thread.sleep((long) (Math.random() * 1000));  	//模拟写操作
            this.data = data;  
            System.out.println(Thread.currentThread().getName() + " ........写入的数据: " + data);  
  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            w.unlock();
        }  
    }  
}  

public class ReentrantReadWriterLockTest{  
  
    public static void main(String[] args) {  
  
        final ReadWrite readWrite = new ReadWrite();  
  
        for (int i = 0; i < 3; i++) {  		//创建并启动3个读线程
        	new Thread(new Runnable() {   
                
                @Override  
                public void run() {  
                    readWrite.put(new Random().nextInt(8));	//随机写入一个数据
                }  
            }).start();                        
        }  
        
        for(int i=0;i<9;i++){				//创建并启动了9个写线程
        	new Thread(new Runnable() {  
        		  
                @Override  
                public void run() {  
                    readWrite.get();  	
  
                }  
            }).start();   
        }
          
    }  
}  

部分输出:

Thread-0 +++++++准备写数据!
Thread-0 ........写入的数据: 7
Thread-1 +++++++准备写数据!
Thread-1 ........写入的数据: 6
Thread-2 +++++++准备写数据!
Thread-2 ........写入的数据: 3
Thread-5**准备读数据!
Thread-4**准备读数据!
Thread-3**准备读数据!

说明:可以看出:看出输出中准备写数据和写入的数据时成对出现的,印证了当获取写锁后,其他线程对于读锁和写锁的获取均被阻塞。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值