首页 > 代码库 > Java-No.06 读写锁控制缓存失效照成的Dogpile效应

Java-No.06 读写锁控制缓存失效照成的Dogpile效应

package cn.guagua.mobile.common;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.apache.log4j.Logger;

import cn.guagua.mobile.cache.redis.Redis;

/**
 * 读写锁控制强制读取缓存同步
 * @author shma
 * @date 2014-10-11 15:04:28
 */
public class SynchCacheLock<T> {

	private static final Logger logger = Logger.getLogger(SynchCacheLock.class);
	
	private static Redis.RedisClient redis1 = new Redis.RedisClient("1");
	
	private ReadWriteLock lock = null;
	private Lock readLock = null; // 读锁
    private Lock writeLock = null; // 写锁
	
	public SynchCacheLock() {
		lock = new ReentrantReadWriteLock();
		readLock = lock.readLock();
		writeLock = lock.writeLock();
		System.out.println(Thread.currentThread().getName() + ">>> cache lock init...");
	}
	
	public T getCache(String key, Runnable task) {
		T obj = null;
		readLock.lock();
		try {
			obj = (T) redis1.getObject(key);
			if(obj == null) {
				System.out.println(Thread.currentThread().getName() + " read request " + key + " is null, wait query...");
				readLock.unlock();
				writeLock.lock();
				try {
					obj = (T) redis1.getObject(key);
					if(obj == null) {
						task.run();//强制执行执行写缓存任务
						System.out.println(Thread.currentThread().getName() + " read request " + key + " end...");
						obj = (T) redis1.getObject(key);
					}
				} catch(Throwable e) {
					System.out.println("readLock error...");
					e.printStackTrace();
				} finally {
					readLock.lock();
		            writeLock.unlock();
				}
			}
			System.out.println(Thread.currentThread().getName() + " read request " + key + " data...");
		} catch(Throwable e) {
			System.out.println("lock error...");
			e.printStackTrace();
		} finally {
			readLock.unlock();
		}

		return obj;
	}
}


Java-No.06 读写锁控制缓存失效照成的Dogpile效应