zoukankan      html  css  js  c++  java
  • 读写锁ReentrantReadWriteLock:读读共享,读写互斥,写写互斥

    介绍

    DK1.5之后,提供了读写锁ReentrantReadWriteLock,读写锁维护了一对锁:一个读锁,一个写锁。通过分离读锁和写锁,使得并发性相比一般的排他锁有了很大提升。在读多写少的情况下,读写锁能够提供比排他锁更好的并发性和吞吐量。

    源码定义

    /* 
    * <p>This lock supports a maximum of 65535 recursive write locks
     * and 65535 read locks. Attempts to exceed these limits result in
     * {@link Error} throws from locking methods.
     *
     * @since 1.5
     * @author Doug Lea
     */
    public class ReentrantReadWriteLock
            implements ReadWriteLock, java.io.Serializable {
        private static final long serialVersionUID = -6992448646407690164L;
        /** Inner class providing readlock */
        private final ReentrantReadWriteLock.ReadLock readerLock;
        /** Inner class providing writelock */
        private final ReentrantReadWriteLock.WriteLock writerLock;
        /** Performs all synchronization mechanics */
        final Sync sync;
        ...
    }

    code

    public class ReentrantReadWriteLockTest {
        ReentrantReadWriteLock lock;
        private ReentrantReadWriteLock.ReadLock readLock;
        private ReentrantReadWriteLock.WriteLock writeLock;
    
        private ReentrantReadWriteLockTest() {
            lock = new ReentrantReadWriteLock();
            readLock = lock.readLock();
            writeLock = lock.writeLock();
        }
    
        public void read() {
            try {
                readLock.lock();
                System.out.println(Thread.currentThread().getName() + " 开始读了。。。");
                Thread.sleep(3000);
            }catch (InterruptedException e) {
    
            }finally {
                System.out.println(Thread.currentThread().getName() + " 读结束了。。。");
                readLock.unlock();
            }
        }
    
        public void write() {
            try {
                writeLock.lock();
                System.out.println(Thread.currentThread().getName() + " 开始写了。。。");
                Thread.sleep(3000);
            } catch (InterruptedException e) {
    
            } finally {
                System.out.println(Thread.currentThread().getName() + " 写完了。。。");
                writeLock.unlock();
            }
    } }

    测试1

     public static void main(String[] args) {
            final ReentrantReadWriteLockTest test = new ReentrantReadWriteLockTest();
            Thread t1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    test.read();
    
                }
            }, "ReadThread1");
            Thread t2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    test.read();
                }
            }, "ReadThread2");
            Thread t3 = new Thread(new Runnable() {
                @Override
                public void run() {
                    test.write();
                }
            }, "WriteThread1");
            Thread t4 = new Thread(new Runnable() {
                @Override
                public void run() {
                    test.write();
                }
            }, "WriteThread4");
    
            t1.start();
            t2.start();
        }

    输出

    ReadThread1 开始读了。。。
    ReadThread2 开始读了。。。
    ReadThread1 读结束了。。。
    ReadThread2 读结束了。。。
    

    结论:读读共享  

    测试2

    t2.start();
    t3.start();

    输出

    ReadThread2 开始读了。。。
    ReadThread2 读结束了。。。
    WriteThread1 开始写了。。。
    WriteThread1 写完了。。。
    

    结论:读写互斥

    测试3

    t4.start();
    t3.start();

    输出

    WriteThread4 开始写了。。。
    WriteThread4 写完了。。。
    WriteThread1 开始写了。。。
    WriteThread1 写完了。。。
    

    结论:写写互斥

    注意:新生成变量时,要用final修饰

    final ReentrantReadWriteLockTest test = new ReentrantReadWriteLockTest();

    原因:从内部类访问本地变量,本地变量要被声明为final类型

  • 相关阅读:
    Android Activity生命周期
    Android 横屏切换竖屏Activity的生命周期(转)
    (引用)mysql总结(二)
    (转载)mysql指令总结
    (引用)性能测试没有告诉你的
    参数化(引用)
    (引用)什么时候开展性能(二)
    (引用)什么时候开展性能(一)
    性能测试中容易混淆的概念
    浏览器内核
  • 原文地址:https://www.cnblogs.com/kaituorensheng/p/10631112.html
Copyright © 2011-2022 走看看