您的位置:首页 > 其它

基于synchronized 或 ReadWriteLock实现 简单缓存机制

2016-12-02 12:45 671 查看
package cn.xxx.xxx;

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

public class CacheDemo_My {

public static void main(String[] args) {
// 内部类 实例化时需要在 内部类前加static 关键字
final CacheClass cacheClass = new CacheClass();
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {

@Override
public void run() {
Object valueObject = cacheClass.getData("1");
System.out.println(Thread.currentThread().getName() + " : " + valueObject);
}
}).start();
}
}

static class CacheClass {
private Map<String, Object> cacheMap = new HashMap<String, Object>();

/**
* 1.0 没有考虑并发 问题: 从数据库查了两次
* 从数据库查询数据!
* 从数据库查询数据!
*  Thread-1 : null 为什么是null,并发了,过程如 Thread-0 所示
*  Thread-2 : aaa
*  Thread-0 :null  为什么是null,因为第一次读取map中没有值返回null,而cacheMap.put(key, "aaa")后
*             并没有重新赋值给object  所以是null
*             解决方案是 直接从cacheMap.get(key) 中获取,不要中间环节 object,这里我就不改了
*  Thread-3 : aaa
*  Thread-4 : aaa
*  Thread-5 : aaa
*  Thread-6 : aaa
*  Thread-7 : aaa
*  Thread-8: aaa
*  Thread-9 : aaa
*
* @param key
* @return
*/
// public Object getData(String key) {
// Object value = cacheMap.get(key);
// if (value == null) {
// System.out.println("从数据库查询数据!");
// cacheMap.put(key, "aaa");
// }
// return value;
// }

/**
* 2.0 使用synchronized 同步 代码块 解决并发问题 实现方式简单 直接加synchronized 关键字
*
* 从数据库查询数据!
*  Thread-4 : bbb
*  Thread-1 : bbb
*  Thread-2 : bbb
*  Thread-0 : bbb
*  Thread-3 : bbb
*  Thread-8 : bbb
*  Thread-7 : bbb
*  Thread-6 : bbb
*  Thread-9 : bbb
*  Thread-5 : bbb
*
* @param key
* @return
*/
//         public synchronized Object getData(String key){
//
//         if ( cacheMap.get(key)==null) {
//         System.out.println("从数据库查询数据!");
//         cacheMap.put(key, "bbb");
//         }
//         return cacheMap.get(key);
//         }

/**
* 3.0 使用读写锁
*
从数据库查询数据!
Thread-1 : ccc
Thread-3 : ccc
Thread-4 : ccc
Thread-2 : ccc
Thread-0 : ccc
Thread-5 : ccc
Thread-7 : ccc
Thread-8 : ccc
Thread-9 : ccc
Thread-6 : ccc
*/
private  ReadWriteLock rwl = new ReentrantReadWriteLock();
public Object getData(String key) {
//加锁了就要try finally ,避免异常情况下 代码一直被锁
rwl.readLock().lock();
try {
if (cacheMap.get(key) == null) {
try{
//读锁 解掉 是为了写锁 加锁
rwl.readLock().unlock();
//加锁了就要try finally ,避免异常情况下 代码一直被锁
rwl.writeLock().lock();
// 避免第一个线程写完数据,后面的线程接着写
if (cacheMap.get(key) == null) {
System.out.println("从数据库查询数据!");
cacheMap.put(key, "ccc");
}
}
finally{
rwl.writeLock().unlock();
}
rwl.readLock().lock();
}
} finally {
rwl.readLock().unlock();
}

return cacheMap.get(key);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: