ReadWriteLock如何使用?

ReadWriteLock,读写锁。
ReentrantReadWriteLock 是 ReadWriteLock 的一种实现。

 

特点:

  • 包含一个 ReadLock 和 一个 WriteLock 对象
  • 读锁与读锁不互斥;读锁与写锁,写锁与写锁互斥
  • 适合对共享资源有读和写操作,写操作很少,读操作频繁的场景
  • 可以从写锁降级到读锁。获取写锁->获取读锁->释放写锁
  • 无法从读锁升级到写锁
  • 读写锁支持中断
  • 写锁支持Condition;读锁不支持Condition

 

示例1--根据 key 获取 value 值

private ReadWriteLock lock = new ReentrantReadWriteLock();//定义读写锁
 
//根据 key 获取 value 值
public Object getValue(String key){
	//使用读写锁的基本结构
	lock.readLock().lock();//加读锁
	Object value = null;
	try{
		value = cache.get(key);
		if(value == null){
			lock.readLock().unlock();//value值为空,释放读锁
			lock.writeLock().lock();//加写锁,写入value值
			try{
				//重新检查 value值是否已经被其他线程写入
				if(value == null){
					value = "value";//写入数据
				}
			}finally{
				lock.writeLock().unlock();
			}
			lock.readLock().lock();
		}
	}finally{
		lock.readLock().unlock();
	}
	return value;
}

  

 

示例2--多线程环境下的读写锁使用

package constxiong.interview;
 
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
 
/**
 * 测试可重入 读写锁
 * @author ConstXiong
 * @date 2019-06-10 11:19:42
 */
public class TestReentrantReadWriteLock {
    
    private Map<String, Object> map = new HashMap<String, Object>();
    
    private ReadWriteLock lock = new ReentrantReadWriteLock();
    
    /**
     * 根据 key 获取 value
     * @param key
     * @return
     */
    public Object get(String key) {
        Object value = null;
        lock.readLock().lock();
        try {
            Thread.sleep(50L);
            value = map.get(key);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.readLock().unlock();
        }
        return value; 
    }
    
    /**
     * 设置key-value
     * @param key
     * @return
     */
    public void set(String key, Object value) {
        lock.writeLock().lock();
        try {
            Thread.sleep(50L);
            map.put(key, value);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.writeLock().unlock();
        }
    }
 
    //测试5个线程读数据,5个线程写数据
    public static void main(String[] args) {
        final TestReentrantReadWriteLock test = new TestReentrantReadWriteLock();
        final String key = "lock";
        final Random r = new Random();
        for (int i = 0; i <5; i++) {
            new Thread(){
                @Override
                public void run() {
                    for (int j = 0; j <10; j++) {
                        System.out.println(Thread.currentThread().getName() + " read value=" + test.get(key));
                    }
                }
            }.start();
            
            new Thread(){
                @Override
                public void run() {
                    for (int j = 0; j <10; j++) {
                        int value = r.nextInt(1000);
                        test.set(key, value);
                        System.out.println(Thread.currentThread().getName() + " write value=" + value);
                    }
                }
            }.start();
        }
    }
    
}

 


原文链接
 


 

所有资源资源汇总于公众号



 

 

posted @ 2019-12-11 09:07  ConstXiong  阅读(424)  评论(0编辑  收藏  举报