基于synchronized 或 ReadWriteLock实现 简单缓存机制
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);
}
}
}
基于synchronized 或 ReadWriteLock实现 简单缓存机制的更多相关文章
- 常见面试题之操作系统中的LRU缓存机制实现
LRU缓存机制,全称Least Recently Used,字面意思就是最近最少使用,是一种缓存淘汰策略.换句话说,LRU机制就是认为最近使用的数据是有用的,很久没用过的数据是无用的,当内存满了就优先 ...
- 基于Server-Sent Event的简单聊天室 Web 2.0时代,即时通信已经成为必不可少的网站功能,那实现Web即时通信的机制有哪些呢?在这门项目课中我们将一一介绍。最后我们将会实现一个基于Server-Sent Event和Flask简单的在线聊天室。
基于Server-Sent Event的简单聊天室 Web 2.0时代,即时通信已经成为必不可少的网站功能,那实现Web即时通信的机制有哪些呢?在这门项目课中我们将一一介绍.最后我们将会实现一个基于S ...
- 简单的Map缓存机制实现
大致思路是用一个单例的Map实现,当然此Map得是线程安全的--ConcurrentHashMap 原本项目需求是缓存十条消息,所以打算用Map实现缓存机制.中途夭折下面具体尚未实现... 当然此代码 ...
- 【腾讯Bugly干货分享】彻底弄懂 Http 缓存机制 - 基于缓存策略三要素分解法
本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/qOMO0LIdA47j3RjhbCWUEQ 作者:李 ...
- Http协议:彻底弄懂 Http 缓存机制 - 基于缓存策略三要素分解法
转载:http://mp.weixin.qq.com/s/uWPls0qrqJKHkHfNLmaenQ 导语 Http 缓存机制作为 web 性能优化的重要手段,对从事 Web 开发的小伙伴们来说是必 ...
- mybatis缓存机制
目录 mybatis缓存机制 Executor和缓存 一级缓存 小结 二级缓存 小结 mybatis缓存机制 mybatis支持一.二级缓存来提高查询效率,能够正确的使用缓存的前提是熟悉mybatis ...
- Lock、synchronized和ReadWriteLock,StampedLock戳锁的区别和联系以及Condition
https://www.cnblogs.com/RunForLove/p/5543545.html 先来看一段代码,实现如下打印效果: 1 2 A 3 4 B 5 6 C 7 8 D 9 10 E 1 ...
- 聊聊MyBatis缓存机制【美团-推荐】
聊聊MyBatis缓存机制 2018年01月19日 作者: 凯伦 文章链接 18778字 38分钟阅读 前言 MyBatis是常见的Java数据库访问层框架.在日常工作中,开发人员多数情况下是使用My ...
- Volley源码解析(三) 有缓存机制的情况走缓存请求的源码分析
Volley源码解析(三) 有缓存机制的情况走缓存请求的源码分析 Volley之所以高效好用,一个在于请求重试策略,一个就在于请求结果缓存. 通过上一篇文章http://www.cnblogs.com ...
随机推荐
- ip地址转换
通常,我们用点分十进制字符串表示ipv4地址(192.168.1.1),用十六进制字符串表示ipv6地址(fe80::20c:29ff:fee9:4bcc). ipv4转换函数 #include &l ...
- NSIS对话框单位造成的控件移位问题
在使用NSIS脚本开发安装卸载程序,使用自定义的nsdialog控件.发现在小部分系统上安装时,一些控件会消失,或者挪位.于是排除问题,看看这些控件的为位置和坐标,发现基本上是使用了对话框单位的控件, ...
- spark 快速入门 java API
Spark的核心就是RDD,对SPARK的使用入门也就是对RDD的使用,包括action和transformation 对于Java的开发者,单单看文档根本是没有办法理解每个API的作用的,所以每个S ...
- mysql 命令导入导出
导出 mysqldump -u 用户名 -p 数据库名 > 导出的文件名mysqldump -u root -p dataname >xxx.sql 导入 mysql>source ...
- memcache的内存管理探微
slab分配器:http://blog.csdn.net/luotuo44/article/details/42737181 hash操作 :http://blog.csdn.net/luotuo4 ...
- mui学习记录
1.页面间传值 2.mui如何增加自定义icon图标 http://ask.dcloud.net.cn/article/128 3.设计基于HTML5的APP登录功能及安全调用接口的方式(原理篇) h ...
- CC2540自己的配置文件
首先要指出,字段属性有notify的不能同时有read,write属性,别问哥,哥也不知道,反正我做的就不能notify,只能read,write. 分享的程序段第一字段有notify属性,第二字段r ...
- js方法入参或局部变量和全局变量重名,用来赋值全局变量会失败
今天遇到个bug,最后终于知道原因了,js方法入参和全局变量重名,用入参赋值全局变量失败,就是说方法入参不能和全局变量重名. 现在下面的例子也说明,局部变量和全局变量不可以同名不光是入参,只要同名赋值 ...
- java垃圾回收机制
1 .垃圾回收机制(GC)垃圾回收就是回收内存中不再使用对象:(1)垃圾回收的步骤:1)查找内存中不再使用的对象:2)释放这些对象所占用的内存:(2)查找内存中不再使用的对象方法:1)引用计数法如果一 ...
- libsvm数据处理初略流程