美文网首页
读写锁 ReadWriteLock

读写锁 ReadWriteLock

作者: 程序员网址导航 | 来源:发表于2019-05-18 14:55 被阅读0次

    RelaxHeart网 - Tec博客: 我的更多文章

    ReadWriteLock


    ReadWriteLock是JDK5中提供的读写分离锁。读写分离锁可以有效地帮助减少锁竞争,以提高系统性能。用锁分离的机制来提升性能非常容易理解,比如线程A1,A2,A3进行写操作,B1,B2,B3进行读操作,如果使用重入锁或者内部锁(synchronized)则论路上说所有读之间、读与写之间、写与写之间都是穿行操作的。当B1进行读取时,B2、B3则需要等待锁。由于读操作并不对数据的完整性造成破坏,这种等待显然是不合理的。因此,读写锁就有了发挥功能的余地。

    在这种情况下,读写锁允许多个线程同时读,使得B1,B2,B3之间真正并行。但是,考虑都数据完整性,写写操作和读写操作间依然时需要相互等待和持有锁的。总的来说,读写锁的访问约束如下表:

    image.png

    使用示例


    如果在系统中,读操作次数远远大于写操作,则读写锁就可以发挥最大的功效,提升系统的性能。这里我给出一个稍微夸张点的案例,来说明读写锁对性能的帮助:

    /**
     * @Author: 王琦 <QQ.Eamil>1124602935@qq.com</QQ.Eamil>
     * @Date: 2019-5-4 0004 9:17
     * @Description: 读写锁案例
     */
    public class ReadWriteLockDemo {
    
        private static Lock lock = new ReentrantLock();
        private static ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
        private static Lock readLock = readWriteLock.readLock();
        private static Lock writeLock = readWriteLock.writeLock();
        private int val;
    
        /**
         * 处理读操作
         *
         * @throws InterruptedException
         */
        public Object handleRead(Lock lock) throws InterruptedException {
            try {
                // 模拟读操作
                lock.lock();
                // 读操作的耗时越多,读写锁的性能优势就越明显
                Thread.sleep(1000);
                return val;
            } finally {
                lock.unlock();
            }
        }
    
        /**
         * 处理写操作
         *
         * @throws InterruptedException
         */
        public void handleWrite(Lock lock, int index) throws InterruptedException {
            try {
                // 模拟写操作
                lock.lock();
                Thread.sleep(1000);
                val = index;
            } finally {
                lock.unlock();
            }
        }
    
    
        public static void main(String[] args) {
            final ReadWriteLockDemo demo = new ReadWriteLockDemo();
            Runnable readRunnale = new Runnable() {
                @Override
                public void run() {
                    try {
                        demo.handleRead(readLock);
                        demo.handleRead(lock);
                    } 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());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };
    
            for (int i=0; i<18; i++){
                new Thread(readRunnale).start();
            }
    
            for (int i=0; i<2; i++){
                new Thread(writeRunnable).start();
            }
        }
    }
    

    总结


    对于读写锁访问约束如下:
    (1)读-读不互斥:读读之间不阻塞
    (2)读-写互斥:读阻塞写,写也会阻塞读
    (3)写-写互斥:写写阻塞

    相关文章

      网友评论

          本文标题:读写锁 ReadWriteLock

          本文链接:https://www.haomeiwen.com/subject/zyotoqtx.html