ReadWriteLock 如何使用?

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 map = new HashMap();
	
	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();
		}
	}
	
}

 


【Java面试题与答案】整理推荐

  • 基础与语法
  • 集合
  • 网络编程
  • 并发编程
  • Web
  • 安全
  • 设计模式
  • 框架
  • 算法与数据结构
  • 异常
  • 文件解析与生成
  • Linux
  • MySQL
  • Oracle
  • Redis
  • Dubbo

 

你可能感兴趣的:(面试,java并发编程,自做,Java,面试题)