基于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 ...
随机推荐
- PHP 图片上传工具类(支持多文件上传)
====================ImageUploadTool======================== <?php class ImageUploadTool { private ...
- JS 格式化当前时间
Date.prototype.format = function(fmt) { var o = { "M+" : this.getMonth()+1, //月份 "d+& ...
- Linux下的压缩和解压缩命令——tar
tar命令 选项: -c: 建立压缩档案 -x:解压 -t:查看内容 -r:向压缩归档文件末尾追加文件 -u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只 ...
- ASP.NET MVC 5 使用autofac实现DI
使用Nuget添加Autofac.MVC的引用 启动项设置 注册Controller 注册ModelBinder 注册相关的web abstraction 为View层启用属性注入 为Action F ...
- 【krpano】krpano xml资源解密(破解)软件说明与下载(v1.4)
欢迎加入qq群551278936讨论krpano技术以及获取最新软件. 该软件已经不再维护,现在已经被KRPano资源分析工具取代,详情参见 http://www.cnblogs.com/reac ...
- iOS 局部变量 全局变量 成员变量
一.成员变量 : 写在类声明的大括号中的变量叫成员变量 (也叫属性/实例变量) 成员变量不可离开类 离开了类就不是成员变量 成员变量不能再定义的同事初始化 成员量只能通过对象来访问 成员变量存储在堆中 ...
- xposed XDA记录
[OFFICIAL] Xposed for Lollipop/Marshmallow [Android 5.0/5.1/6.0, v86, 2016/10/31] http://forum.xda-d ...
- js下载项目中的文件
项目中有一个连接是下载视频插件,放到服务器上,不能io输出,所以指定地址直接下载 <div id="objInfo"> <jsp:include page=&qu ...
- WinForm跨窗体传值
1.另一窗体建公共变量listdataRow public List<DataGridViewRow> listdataRow = new List<DataGridViewRow& ...
- javaSE基础06
javaSE基础06 一.匿名对象 没有名字的对象,叫做匿名对象. 1.2匿名对象的使用注意点: 1.我们一般不会用匿名对象给属性赋值的,无法获取属性值(现阶段只能设置和拿到一个属性值.只能调用一次方 ...