Java实现一个简单的缓存方法

缓存是在web开发中经常用到的,将程序经常使用到或调用到的对象存在内存中,或者是耗时较长但又不具有实时性的查询数据放入内存中,在一定程度上可以提高性能和效率。下面我实现了一个简单的缓存,步骤如下。

创建缓存对象EntityCache.java

public class EntityCache {

  /**

   * 保存的数据

   */

  private Object datas;

  /**

   * 设置数据失效时间,为0表示永不失效

   */

  private long timeOut;

  /**

   * 最后刷新时间

   */

  private long lastRefeshTime;

  public EntityCache(Object datas, long timeOut, long lastRefeshTime) {

    this.datas = datas;

    this.timeOut = timeOut;

    this.lastRefeshTime = lastRefeshTime;

  }

  public Object getDatas() {

    return datas;

  }

  public void setDatas(Object datas) {

    this.datas = datas;

  }

  public long getTimeOut() {

    return timeOut;

  }

  public void setTimeOut(long timeOut) {

    this.timeOut = timeOut;

  }

  public long getLastRefeshTime() {

    return lastRefeshTime;

  }

  public void setLastRefeshTime(long lastRefeshTime) {

    this.lastRefeshTime = lastRefeshTime;

  }

}

定义缓存操作接口,ICacheManager.java

public interface ICacheManager {

  /**

   * 存入缓存

   * @param key

   * @param cache

   */

  void putCache(String key, EntityCache cache);

  /**

   * 存入缓存

   * @param key

   * @param cache

   */

  void putCache(String key, Object datas, long timeOut);

  /**

   * 获取对应缓存

   * @param key

   * @return

   */

  EntityCache getCacheByKey(String key);

  /**

   * 获取对应缓存

   * @param key

   * @return

   */

  Object getCacheDataByKey(String key);

  /**

   * 获取所有缓存

   * @param key

   * @return

   */

  Map<String, EntityCache> getCacheAll();

  /**

   * 判断是否在缓存中

   * @param key

   * @return

   */

  boolean isContains(String key);

  /**

   * 清除所有缓存

   */

  void clearAll();

  /**

   * 清除对应缓存

   * @param key

   */

  void clearByKey(String key);

  /**

   * 缓存是否超时失效

   * @param key

   * @return

   */

  boolean isTimeOut(String key);

  /**

   * 获取所有key

   * @return

   */

  Set<String> getAllKeys();

}

实现接口ICacheManager,CacheManagerImpl.java

这里我使用了ConcurrentHashMap来保存缓存,本来以为这样就是线程安全的,其实不然,在后面的测试中会发现它并不是线程安全的。

public class CacheManagerImpl implements ICacheManager {

  private static Map<String, EntityCache> caches = new ConcurrentHashMap<String, EntityCache>();

  /**

   * 存入缓存

   * @param key

   * @param cache

   */

  public void putCache(String key, EntityCache cache) {

    caches.put(key, cache);

  }

  /**

   * 存入缓存

   * @param key

   * @param cache

   */

  public void putCache(String key, Object datas, long timeOut) {

    timeOut = timeOut > 0 ? timeOut : 0L;

    putCache(key, new EntityCache(datas, timeOut, System.currentTimeMillis()));

  }

  /**

   * 获取对应缓存

   * @param key

   * @return

   */

  public EntityCache getCacheByKey(String key) {

    if (this.isContains(key)) {

      return caches.get(key);

    }

    return null;

  }

  /**

   * 获取对应缓存

   * @param key

   * @return

   */

  public Object getCacheDataByKey(String key) {

    if (this.isContains(key)) {

      return caches.get(key).getDatas();

    }

    return null;

  }

  /**

   * 获取所有缓存

   * @param key

   * @return

   */

  public Map<String, EntityCache> getCacheAll() {

    return caches;

  }

  /**

   * 判断是否在缓存中

   * @param key

   * @return

   */

  public boolean isContains(String key) {

    return caches.containsKey(key);

  }

  /**

   * 清除所有缓存

   */

  public void clearAll() {

    caches.clear();

  }

  /**

   * 清除对应缓存

   * @param key

   */

  public void clearByKey(String key) {

    if (this.isContains(key)) {

      caches.remove(key);

    }

  }

  /**

   * 缓存是否超时失效

   * @param key

   * @return

   */

  public boolean isTimeOut(String key) {

    if (!caches.containsKey(key)) {

      return true;

    }

    EntityCache cache = caches.get(key);

    long timeOut = cache.getTimeOut();

    long lastRefreshTime = cache.getLastRefeshTime();

    if (timeOut == 0 || System.currentTimeMillis() - lastRefreshTime >= timeOut) {

      return true;

    }

    return false;

  }

  /**

   * 获取所有key

   * @return

   */

  public Set<String> getAllKeys() {

    return caches.keySet();

  }

}

CacheListener.java,监听失效数据并移除。

public class CacheListener{

  Logger logger = Logger.getLogger("cacheLog");

  private CacheManagerImpl cacheManagerImpl;

  public CacheListener(CacheManagerImpl cacheManagerImpl) {

    this.cacheManagerImpl = cacheManagerImpl;

  }

  public void startListen() {

    new Thread(){

      public void run() {

        while (true) {

          for(String key : cacheManagerImpl.getAllKeys()) {

            if (cacheManagerImpl.isTimeOut(key)) {

             cacheManagerImpl.clearByKey(key);

             logger.info(key + "缓存被清除");

           }

          }

        }

      }

    }.start();

  }

}

测试类TestCache.java

public class TestCache {

  Logger logger = Logger.getLogger("cacheLog");

  /**

   * 测试缓存和缓存失效

   */

  @Test

  public void testCacheManager() {

    CacheManagerImpl cacheManagerImpl = new CacheManagerImpl();

    cacheManagerImpl.putCache("test", "test", 10 * 1000L);

    cacheManagerImpl.putCache("myTest", "myTest", 15 * 1000L);

    CacheListener cacheListener = new CacheListener(cacheManagerImpl);

    cacheListener.startListen();

    logger.info("test:" + cacheManagerImpl.getCacheByKey("test").getDatas());

    logger.info("myTest:" + cacheManagerImpl.getCacheByKey("myTest").getDatas());

    try {

      TimeUnit.SECONDS.sleep(20);

    } catch (InterruptedException e) {

      e.printStackTrace();

    }

    logger.info("test:" + cacheManagerImpl.getCacheByKey("test"));

    logger.info("myTest:" + cacheManagerImpl.getCacheByKey("myTest"));

  }

  /**

   * 测试线程安全

   */

  @Test

  public void testThredSafe() {

    final String key = "thread";

    final CacheManagerImpl cacheManagerImpl = new CacheManagerImpl();

    ExecutorService exec = Executors.newCachedThreadPool();

    for (int i = 0; i < 100; i++) {

      exec.execute(new Runnable() {

        public void run() {

            if (!cacheManagerImpl.isContains(key)) {

              cacheManagerImpl.putCache(key, 1, 0);

            } else {

              //因为+1和赋值操作不是原子性的,所以把它用synchronize块包起来

              synchronized (cacheManagerImpl) {

                int value = (Integer) cacheManagerImpl.getCacheDataByKey(key) + 1;

                cacheManagerImpl.putCache(key,value , 0);

              }

            }

        }

      });

    }

    exec.shutdown();

    try {

      exec.awaitTermination(1, TimeUnit.DAYS);

    } catch (InterruptedException e1) {

      e1.printStackTrace();

    }

    logger.info(cacheManagerImpl.getCacheDataByKey(key).toString());

  }

}

来源:http://www.jb51.net/article/111518.htm

原文地址:https://www.cnblogs.com/kongxc/p/8541930.html

时间: 2024-08-08 22:08:40

Java实现一个简单的缓存方法的相关文章

哪种缓存效果高?开源一个简单的缓存组件j2cache

背景 现在的web系统已经越来越多的应用缓存技术,而且缓存技术确实是能实足的增强系统性能的.我在项目中也开始接触一些缓存的需求. 开始简单的就用jvm(java托管内存)来做缓存,这样对于单个应用服务器来说很好. 为了系统的可用性,需要做灾备,那么就要多准备一套系统环境,这时就会有一些共享资源的问题,比如Tomcat的session共享出来 几个系统会公用一套缓存数据,这样就变成一个共享池 需求的增长也就带来了系统的变化,也正为这种变化我开始思考怎么让这些代码兼容,并为以后的系统模块提供比较统一

java线程的简单实现及方法

java线程: 线程是一个程序内部的顺序控制流. cpu实际上在一个时间点上,只执行一个.只不过我们把cpu分成了多个时间片,由于速度很快,我们看起来像是多个线程.. 就像你的时间分成几片,这样 整体看来做事情有规律,效率就会高,何况是cpu呢. 线程的创建和启动: 方法一: java线程通过java.lang.Thread类来实现. VM启动时会有一个主方法所定义的线程, 每一个线程是Tread对象通过它的run()方法来完成操作. 启动线程方式:Thread的start()方法. 如下代码:

java创建一个简单的小框架frame

import java.awt.*; import javax.swing.*; public class SimpleFrameTest { public static void main(String[] args) { EventQueue.invokeLater(new Runnable(){ // 开一个线程 public void run() { SimpleFrame frame = new SimpleFrame(); frame.setTitle("记事本"); //

利用java实现一个简单的远程监控程序

一般的远程监控软件都是用c或者c++等语言开发的,而使用java如何来实现相同的功能呢. 首先我们先介绍一下一个简单的远程监控程序的实现原理. 功能一,远程屏幕监视 (1) 必须要有监控端与被监控端,而且程序保持启动. (2) 被监控端获取本机的屏幕截屏发图给监控端. (3) 监控端在本地窗口中显示被监控端发送过来的图像. (4) (2)(3)步骤重复执行,这时在监控端即可实时监视到被监控端的桌面操作了. 功能二,远程控制 (1) 必须要有监控端与被监控端,而且程序保持启动. (2) 在监控端监

java动态缓存成长小纪(一)——创建一个简单的缓存

在实际项目中,我们经常会需要使用到缓存.一般来说,缓存介质是内存:而常见的DB将数据存储在硬盘中的:缓存读取是电脉冲,而硬盘读取是机械地读取转动的硬盘,速度差异是上百倍的.所以往往可以通过缓存,对经常用到的数据进行访问,以提高速度. 创建缓存实际上就是针对两个对象,1. Cache对象,即一个缓存对象:2. CacheManager对象,即一个管理不同缓存的对象,其核心实际上就是一个Map,用来保存与获取不同缓存. 最简单的缓存 实现如下: /** * 项目名称: * 文件说明:创建一个缓存管理

Java写一个简单学生管理系统

其实作为一名Java的程序猿,无论你是初学也好,大神也罢,学生管理系统一直都是一个非常好的例子,初学者主要是用数组.List等等来写出一个简易的学生管理系统,二.牛逼一点的大神则用数据库+swing来做一个有界面的学生管理系统.其实都并不会太难. 今天我就先写一个简单的用List来实现学生管理系统: 首先,管理系统是针对学生对象的,所以我们先把学生对象就写出来: package bean; public class Student { String name; String studentId;

java实现一个简单的Web服务器

Web服务器也称为超文本传输协议服务器,使用http与其客户端进行通信,基于java的web服务器会使用两个重要的类, java.net.Socket类和java.net.ServerSocket类,并基于发送http消息进行通信. 这个简单的Web服务器会有以下三个类: *HttpServer *Request *Response 应用程序的入口在HttpServer类中,main()方法创建一个HttpServer实例,然后调用其await()方法,顾名思义,await()方法会在指定端口

如何设计Java框架----一个简单的例子【翻译】

原文:http://www.programcreek.com/2011/09/how-to-design-a-java-framework/ 原文和翻译都只是参考,如有不对,欢迎指正. 你可能会好奇框架是如何工作的,我会创建一个简单的框架来演示一下. 框架的目标首先,为什么我们需要框架而不是库呢?框架的目标是定义一个让开发者实现基于个性化需求的某些功能的过程,换句话说,框架定义了骨架而开发者进行填补. 简单的框架在下面的例子中,前三个类是框架的一部分,第四个类是该框架的客户端代码. Main.j

利用java实现一个简单的链表结构

定义: 所谓链表就是指在某节点存储数据的过程中还要有一个属性用来指向下一个链表节点,这样的数据存储方式叫做链表 链表优缺点: 优点:易于存储和删除 缺点:查询起来较麻烦 下面我们用java来实现如下链表结构: 首先定义节点类: 复制代码package LinkTest;/** 链表节点类 @author admin */public class Node {private int value;//存储数据private Node next;//下一个节点/** 定义构造器 @param vlau