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实现 简单缓存机制的更多相关文章

  1. 常见面试题之操作系统中的LRU缓存机制实现

    LRU缓存机制,全称Least Recently Used,字面意思就是最近最少使用,是一种缓存淘汰策略.换句话说,LRU机制就是认为最近使用的数据是有用的,很久没用过的数据是无用的,当内存满了就优先 ...

  2. 基于Server-Sent Event的简单聊天室 Web 2.0时代,即时通信已经成为必不可少的网站功能,那实现Web即时通信的机制有哪些呢?在这门项目课中我们将一一介绍。最后我们将会实现一个基于Server-Sent Event和Flask简单的在线聊天室。

    基于Server-Sent Event的简单聊天室 Web 2.0时代,即时通信已经成为必不可少的网站功能,那实现Web即时通信的机制有哪些呢?在这门项目课中我们将一一介绍.最后我们将会实现一个基于S ...

  3. 简单的Map缓存机制实现

    大致思路是用一个单例的Map实现,当然此Map得是线程安全的--ConcurrentHashMap 原本项目需求是缓存十条消息,所以打算用Map实现缓存机制.中途夭折下面具体尚未实现... 当然此代码 ...

  4. 【腾讯Bugly干货分享】彻底弄懂 Http 缓存机制 - 基于缓存策略三要素分解法

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/qOMO0LIdA47j3RjhbCWUEQ 作者:李 ...

  5. Http协议:彻底弄懂 Http 缓存机制 - 基于缓存策略三要素分解法

    转载:http://mp.weixin.qq.com/s/uWPls0qrqJKHkHfNLmaenQ 导语 Http 缓存机制作为 web 性能优化的重要手段,对从事 Web 开发的小伙伴们来说是必 ...

  6. mybatis缓存机制

    目录 mybatis缓存机制 Executor和缓存 一级缓存 小结 二级缓存 小结 mybatis缓存机制 mybatis支持一.二级缓存来提高查询效率,能够正确的使用缓存的前提是熟悉mybatis ...

  7. 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 ...

  8. 聊聊MyBatis缓存机制【美团-推荐】

    聊聊MyBatis缓存机制 2018年01月19日 作者: 凯伦 文章链接 18778字 38分钟阅读 前言 MyBatis是常见的Java数据库访问层框架.在日常工作中,开发人员多数情况下是使用My ...

  9. Volley源码解析(三) 有缓存机制的情况走缓存请求的源码分析

    Volley源码解析(三) 有缓存机制的情况走缓存请求的源码分析 Volley之所以高效好用,一个在于请求重试策略,一个就在于请求结果缓存. 通过上一篇文章http://www.cnblogs.com ...

随机推荐

  1. 异步select

    server coding: #!/usr/bin/python # -*- coding: utf-8 -*- import select import socket import sys impo ...

  2. linux Mint wine安装qq,桌面快捷键配置

    在桌面新建qq.desktop文件,添加以下内容 #!/usr/bin/env xdg-open[Desktop Entry]Comment=QQTerminal=falseName=QQExec=w ...

  3. html5 选择元素

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. 在WebPart中获取Office 365中的未读邮件数

    // Create the web request HttpWebRequest request = WebRequest.Create("https://outlook.office365 ...

  5. OpenGL中坐标系的理解(一)

    在OpenGL中,存在着至少存在着三种矩阵,对应着函数glMatrixMode()的三个参数:GL_MODELVIEW,GL_PROJECTION,GL_TEXTURE. 以下主要描述GL_MODEL ...

  6. Web前端之jQuery 的10大操作技巧

    不管是做什么事情,人们习惯在工作中去找方法.找技巧,来帮助提高效率,在软件开发中更是如此.jQuery作为前端开发必学技术之一,在使用中也有各种各样的小技巧,今天小编为大家分享10条必知会的技巧,希望 ...

  7. 泛型T的类型获取

    T.getClass()或者T.class都是非法的,因为T是泛型变量. 由于一个类的类型是什么是在编译期处理的,故不能在运行时直接在Base里得到T的实际类型. /** * 可以在service层直 ...

  8. 给DOM生成的元素添加事件

    问题:通过js给页面添加新元素,并给该元素添加绑定事件,但新添加的元素上却没有绑定任何事件. 常见例子:在处理表格的时候,每行行末有个删除按钮,如下图.点击删除按钮的时候删除这一行. //html部分 ...

  9. Eclipse下配置javaweb项目快速部署到tomcat

    用惯了VS,再用Eclipse,完全有一种从自动挡到手动挡的感觉啊. 很多同学在Eclipse下开发web项目,每一次修改代码,看效果的时候都有右键项目->Run as -> Run on ...

  10. 【Java EE 学习 69 中】【数据采集系统第一天】【SSH框架搭建】

    经过23天的艰苦斗争,终于搞定了数据采集系统~徐培成老师很厉害啊,明明只是用了10天就搞定的项目我却做了23天,还是模仿的...呵呵,算了,总之最后总算是完成了,现在该好好整理该项目了. 第一天的内容 ...