并发编程--读写锁

2018-09-15  本文已影响0人  守住阳光

        读写锁维护一对锁,一个读锁和一个写锁。读写锁在同一时刻允许多个读线程获取读锁;但是同一时刻只能有一个线程获取到写锁,此时其他读写操作均被阻塞。并发性相比其他排他锁有了很大的提升。

一、读写锁的特性

        1、公平性与非公平性选择

        支持非公平(默认)和公平的锁获取方式,吞吐量非公平优于公平。

        2、重进入

        支持重进入,以读写线程为例:读线程在获取读锁能再次获取读锁。而写线程在获取写锁之后,能再次获取写锁,同时也可以获取读锁。

        3、锁降级

        遵循获取写锁,获取读锁在释放写锁的次序,写锁能降级为读锁。

二、接口与示例

        ReadWriteLock仅定义了获取读锁和写锁的两个方法,即eadLock()方法和writeLock()方法,而其实现——ReentrantReadWriteLock,除了接口方法之外,还提供了一些便于外界监控其内部工作状态的方法,如下:

        1、int getReadLockCount()

        返回当前读锁被获取的次数。

        2、int getReadHoldCount()

        返回当前线程获取读锁的次数。

        3、boolean isWriteLocked()

        判断写锁是否被获取。

        4、int getWriteHoldCount()

        判断当期写锁被获取的次数。

        下面是通过缓存展示读写锁的使用方式。

public class SafeCache {

        private Map <String ,Object> map = new HashMap<String , Object>();

        //读写锁

        private static  ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

        //读锁

        private static Lock rl = rwl.readLock();

        //写锁

        private static Lock wl = rwl.writeLock();

        //获取元素

        public final Object get(String key){

                rl.lock();

                try{

                        return map.get(key);

                }finally{

                        rl.unlock();

                }

         }

        //插入操作

        public final Object put(String key , Object value){

                wl.lock();

                try{

                    return map.put(key, value);

                }finally{

                    wl.unlock();

                }

         }

        //清空元素

        public void clear(){

                wl.lock();

                try{

                    map.clear();

                }finally{

                    wl.unlock();

                }

        }

}

        Cache组合一个非线程安全的HashMap作为缓存的实现,同时使用读写锁的读锁和写锁来保证Cache是线程安全的。在读操作get(String key)方法中,需要获取读锁,这使得并发访问该方法时不会被阻塞。写操作put(String key,Object value)方法和clear()方法,在更新HashMap时必须提前获取写锁,当获取写锁后,其他线程对于读锁和写锁的获取均被阻塞,而只有写锁被释放之后,其他读写操作才能继续。Cache使用读写锁提升读操作的并发性,也保证每次写操作对所有的读写操作的可见性,同时简化了编程方式。

上一篇下一篇

猜你喜欢

热点阅读