利用读写锁模拟一个缓存系统

一次只有一个线程可以占有写模式的读写锁, 但是可以有多个线程同时占有读模式的读写锁. 正是因为这个特性,
当读写锁是写加锁状态时, 在这个锁被解锁之前, 所有试图对这个锁加锁的线程都会被阻塞.
当读写锁在读加锁状态时, 所有试图以读模式对它进行加锁的线程都可以得到访问权, 但是如果线程希望以写模式对此锁进行加锁, 它必须直到所有的线程释放锁.


package multithreading;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;


//利用读写锁模拟一个缓存系统
//session.load(缓存,没有命中再去数据库中查询)没查到抛异常
//session.get(数据库查询)没查到null
public class ReadWriteLockTest {

	//用Map模拟缓存数据
	private Map<String, String> cache=new HashMap<String, String>();
	//control+t可以查看ReadWriteLock集成目录结构
	private ReadWriteLock lock=new ReentrantReadWriteLock();
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}
	
	//读取缓存的时候允许多个线程同时读取(提高效率),但一个时间内只有一个线程能写
	public String getDate(String key){
		
		lock.readLock().lock();//上读锁允许多个线程同时读取
		
		String value=null;
		try {
			value = cache.get(key);//去缓存里取数据
			if(value==null){//缓存中没有数据
				try {
					lock.readLock().unlock();//先释放读锁(此时3个线程同时达到这里)
					lock.writeLock().lock();//让后上写锁(其中一个线程先上了写锁,另外2个就要等后)
					if(value==null){//再次判断(以防第一个线程做完数据库操作后另外2个已经进来的线程再次做读取数据库操作)
						value="queryDB()正在读取数据库(耗时操作)";	
					}
				}finally{
					lock.writeLock().unlock();//释放写锁	
				}
				lock.readLock().lock();//重新上读锁
			}
		}finally{
			lock.readLock().unlock();//最后不管怎么样都要释放读锁
		}
			
		return value;
	}

}


你可能感兴趣的:(利用读写锁模拟一个缓存系统)