读写锁 ReadWriteLock和Synchronized的比较

排他锁:

  • 同一时刻只允许一个线程访问

读写锁:

  • 同一时刻允许多个读线程同时访问,但是写线程访问的时候,所有的读、写都被会被阻塞,适用于读多写少的场景。
  • ReadWriteLock接口和读写锁ReentrantReadWriteLock

读写锁的实现

public class RwLockImpl implements GoodsService{
   
   private Goods goods;
   
   public RwLockImpl(Goods goods){
   	this.goods = goods;
   }
   
   private final ReadWriteLock lock = new ReentrantReadWriteLock();
   //读锁
   private final Lock readLock = lock.readLock();
   //写锁
   private final Lock writeLock = lock.writeLock();

   //读操作
   @Override
   public int getGoodsNum() {
   	readLock.lock();
   	try {
   		ThreadUtils.sleep(5);
   		return this.goods.getCount();
   	}finally{
   		readLock.unlock();
   	}
   }
   //写操作
   @Override
   public void setGoodsSale(int num) {
   	writeLock.lock();
   	try{
   		ThreadUtils.sleep(5);
   		this.goods.changeInfo(num);
   	}finally{
   		writeLock.unlock();
   	}
   }
}

Synchronized实现

public class SyncImpl implements GoodsService{
   
   private Goods  goods;
   
   public SyncImpl(Goods goods){
   	this.goods = goods;
   }

   @Override
   public synchronized int getGoodsNum() {
   	ThreadUtils.sleep(5);
   	return goods.getCount();
   }

   @Override
   public synchronized void setGoodsSale(int num) {
   	ThreadUtils.sleep(5);
   	goods.changeInfo(num);
   }

性能对比
      项目启动3个写线程,每个线程对数据做10次修改。启动3*10个读线程,每个线程读取数据100次,分别用 ReadWriteLock 和 Synchronized 加以实现,对比下效率。

/**
* 排他锁:
* 1、同一时刻只允许一个线程访问
* 
* 读写锁:
* 1、同一时刻允许多个读线程同时访问,但是写线程访问的时候,所有的读、写都被会被阻塞,适用于读多写少的场景。
* 2、ReadWriteLock接口和读写锁ReentrantReadWriteLock
*/
public class ReadWriteLockDemo {
   
   static final int ReadThreadNum = 10;
   static final int WriteThreadNum = 3;

   public static void main(String[] args) {

       Goods goodsInfo = new Goods("Cup",100000,10000);
       //读写锁
//      GoodsService goodsService = new RwLockImpl(goodsInfo);
       //Synchronized锁
       GoodsService goodsService = new SyncImpl(goodsInfo);
       for(int i = 0;i<WriteThreadNum;i++){
           Thread setT = new Thread(new WriteThead(goodsService));
           for(int j=0;j<ReadThreadNum;j++) {
               Thread getT = new Thread(new ReadThead(goodsService));
               getT.start();           	
           }
   		ThreadUtils.sleep(5);
           setT.start();
       }
   }
   
   /**
    * 读线程	 
    */
   public static class ReadThead implements Runnable{
   	
   	public GoodsService service;
   	
   	public ReadThead(GoodsService service){
   		this.service = service;
   	}

   	@Override
   	public void run() {
   		long start = System.currentTimeMillis();
   		for(int i=0;i<100;i++){
   			service.getGoodsNum();
   			ThreadUtils.sleep(5);
   		}
   		long end = System.currentTimeMillis();
   		System.out.println(Thread.currentThread().getName()+" - "+"【读取】商品信息100次耗时"+(end-start)+"ms");
   	}
   }
   
   /**
    * 写线程
    */
   public static class WriteThead implements Runnable{
   	
   	public GoodsService service;
   	
   	public WriteThead(GoodsService service){
   		this.service = service;
   	}

   	@Override
   	public void run() {
   		long start = System.currentTimeMillis();
   		
   		for(int i=0;i<10;i++){
   			ThreadUtils.sleep(5);
   			service.setGoodsSale(50);
   		}
   		
   		long end = System.currentTimeMillis();
   		System.out.println(Thread.currentThread().getName()+" - "+"【修改】商品信息100次耗时"+(end-start)+"ms");
   	}
   }
}

运行结果
在这里插入图片描述
对比发现,当读线程远大于写线程时,ReadWriteLock的效率远大于Synchronized。

点击下载源码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值