读写分离——读写锁ReadWriteLock

来源:互联网 发布:sql server 2008 免费 编辑:程序博客网 时间:2024/04/30 22:32

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

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();        }    }}
性能提升主要是在于读操作时,重入锁串行读取耗时多,而改用读写锁之后读操作变为并发读,节省了时间。

原创粉丝点击