读写分离——读写锁ReadWriteLock

读写锁顾名思义分离读操作和写操作,可以有效的减少锁竞争以提高系统的性能。读写锁提升性能的地方主要在读读操作(读操作不会改变数据的一致性和完整性),而读写、写写、写读操作之间则会互斥造成阻塞。因此,读写锁应用场景适用于读操作次数大于写操作次数,读操作次数远大于写操作次数时,系统性能提升最明显。

ReadWriteLock接口定义了获取读锁和写锁两个方法,接下来对比串行的重入锁,来测试读写锁性能:

public class ReadWriteLockDemo {

    /**
     * 定义重入锁,对比性能
     */
    private static Lock lock = new ReentrantLock();

    /**
     * 定义读写锁,测试读写分离操作效率
     */
    private static ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    private static ReadLock readLock = readWriteLock.readLock();
    private static WriteLock writeLock = readWriteLock.writeLock();

    /**
     * 全局读写变量
     */
    private int value;

    /**
     * 模拟读操作
     * @param lock 使用何种锁
     * @return
     * @throws InterruptedException
     */
    public Object handleRead(Lock lock) throws InterruptedException{
        try {
            lock.lock();
            Thread.sleep(1000);
            return value;
        } finally {
            lock.unlock();
        }
    }

    /**
     * 模拟写操作
     * @param lock 锁
     * @param index 写入值
     * @throws InterruptedException
     */
    public void handleWrite(Lock lock, int index) throws InterruptedException{
        try {
            lock.lock();
            Thread.sleep(1000);
            value = index;
        } finally {
            lock.unlock();
        }
    }

    /**
     * 创建读写两个线程实例,构建多线程模拟
     * @param args
     */
    public static void main(String[] args) {
        final ReadWriteLockDemo demo = new ReadWriteLockDemo();

        Runnable readRunnable = new Runnable() {

            @Override
            public void run() {
                try {
                    int num = (int)demo.handleRead(readLock);
                    //int num = (int)demo.handleRead(lock);
                    System.out.println(num);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        Runnable writeRunnable = new Runnable() {

            @Override
            public void run() {
                try {
                    demo.handleWrite(writeLock, new Random().nextInt());
                    //demo.handleWrite(lock, new Random().nextInt());
                    System.out.println("write now ...");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        for (int i = 0; i < 18; i++) {
            new Thread(readRunnable).start();
        }

        for (int i = 18; i < 20; i++) {
            new Thread(writeRunnable).start();
        }
    }
}
性能提升主要是在于读操作时,重入锁串行读取耗时多,而改用读写锁之后读操作变为并发读,节省了时间。

你可能感兴趣的:(读写分离——读写锁ReadWriteLock)