目录页:https://blog.csdn.net/u011294519/article/details/88367808
1. ReentrantReadWriteLock
1.1. 小声哔哔
见名知意,这是一种读写锁,其实在很多情况下,我们对数据的读取次数远远大于更新修改的次数(比如缓存),而其实在多个线程只是读取数据的时候我们完全没必要加锁。读写锁在写线程访问的时候,所有的读和写都被阻塞。
1.2. 主要方法
构造方法: ReentrantReadWriteLock()默认初始化非公平锁的实例
够着方法:ReentrantReadWriteLock(boolean fair)若传入的参数fair为true则初始化公平锁,若传入false则初始化非公平锁
ReentrantReadWriteLock.WriteLock writeLock():返回读锁
ReentrantReadWriteLock.ReadLock readLock():返回写锁
1.3. 上代码
1.3.1. 简单demo
先开个开胃菜比对一下ReentrantReadWriteLock和synchronized性能
package com.concurrent.aqslock.part9.tryrw;
import java.util.Random; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
/** * 简单的demo,比对ReentrantReadWriteLock和synchronized性能 */ public class RwDemo {
private ReadWriteLock lock = new ReentrantReadWriteLock(); private final Lock getLock = lock.readLock(); private final Lock setLock = lock.writeLock(); private int number;
// 使用synchronized对象锁进行读取锁定 public synchronized int synGetNumber() { try { Thread.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } return number; }
// 使用synchronized对象锁进行修改锁定 public synchronized void synSetNumber(int number) { try { Thread.sleep(10); this.number = number; } catch (InterruptedException e) { e.printStackTrace(); } }
// 使用ReentrantReadWriteLock的读锁进行读取锁锁定 public int rwGetNumber() { try { getLock.lock(); Thread.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } finally { getLock.unlock(); }
return number; }
// 使用ReentrantReadWriteLock的写锁进行写锁锁定 public void rwSetNumber(int number) { try { setLock.lock(); Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } finally { setLock.unlock(); } this.number = number; }
public static void main(String[] arg0) { RwDemo rwDemo = new RwDemo(); for (int i = 0; i < 5; ++i) { for (int k = 0; k < 3; ++k) { new Thread(() -> { long start = System.currentTimeMillis(); for (int j = 0; j <= 10; ++j) { rwDemo.rwGetNumber(); // rwDemo.synGetNumber(); } System.out.println(Thread.currentThread().getName() + "读商品数据耗时:" + (System.currentTimeMillis() - start) + "ms---------"); }).start(); } new Thread(() -> { long start = System.currentTimeMillis(); for (int j = 0; j <= 10; ++j) { Random r = new Random(); rwDemo.rwSetNumber(r.nextInt()); // rwDemo.synSetNumber(r.nextInt()); } System.out.println(Thread.currentThread().getName() + "写商品数据耗时:" + (System.currentTimeMillis() - start) + "ms---------"); }).start(); } } } |
代码位置:aqs-lock模块的part9
运行结果:
使用ReentrantReadWriteLock读写锁
使用synchronized对象锁
可以明显的看出性能差距