一。 首先,需要导入相关工具包,xmemcached-1.4.2.jar 为必须导入的工具包。

二。 进行具体工具类的编写工作,下面直接上代码。

CacheCallback.java

package cache;import java.io.Serializable;/*** 缓存回调接口(供外部实现具体业务逻辑)*    实现此接口提供缓存的key和被缓存的value的具体生产逻辑* @author linwei**/
public interface CacheCallback {public String getKey();public Serializable getValue() throws Exception;}

CacheProvider.java

package cache;/*** 缓存的具体实现* @author linwei**/
public interface CacheProvider {/*** 获取缓存.* * @param key key* @return 缓存的值* @exception 如果获取缓存失败时,抛出此异常*/public CacheValue getCache(String key) throws Exception;/*** 添加缓存.* * @param key key * @param value 缓存的值*/public void addCache(String key,CacheValue value);/*** 更新缓存.* * @param key key * @param value 缓存的值*/public void updateCache(String key,CacheValue value);/*** 删除缓存.* * @param key key */public void deleteCache(String key);}

CacheTemplate.java

package cache;import java.io.Serializable;
import java.util.Date;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/*** 此类提供一种可以为任意方法提供缓存支持的机制.此类是线程安全的.* @author linwei**/
public class CacheTemplate {private final static Logger logger = LoggerFactory.getLogger(CacheTemplate.class);/*** 默认的缓存过期时长:30分钟*/public final static int DEFAULT_EXPIRY = 30 * 60;/*** 默认的缓存过期时长,单位:秒*/private int expiry = DEFAULT_EXPIRY;/*** 在被缓存方法执行失败时,是否使用过期的缓存*/private boolean useOldCacheIfFail = true;private ThreadPoolExecutor threadPool;private CacheProvider cacheProvider;public CacheTemplate(CacheProvider cacheProvider) {this(cacheProvider, true);}public CacheTemplate(CacheProvider cacheProvider, boolean useOldCacheIfFail) {this(cacheProvider, useOldCacheIfFail, DEFAULT_EXPIRY, initDefaultThreadPool());}public CacheTemplate(CacheProvider cacheProvider, boolean useOldCacheIfFail, int expiry, ThreadPoolExecutor threadPool) {this.cacheProvider = cacheProvider;this.expiry = expiry;this.useOldCacheIfFail = useOldCacheIfFail;this.threadPool = threadPool;}//设置初始默认线程池private static ThreadPoolExecutor initDefaultThreadPool() {ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 10, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(20));threadPool.allowCoreThreadTimeOut(true);return threadPool;}/*** 执行带有缓存的方法.* * @param callback*            CacheCallback接口实现* @return 返回结果* @throws Exception*             执行带有缓存的方法失败时,抛出此异常*/public Object execute(CacheCallback callback) throws Exception {return execute(callback, this.expiry);}/*** * @param callback*             CacheCallback接口实现* @param expiry*            缓存的过期时长,单位:秒* @return 返回结果* @throws Exception*              执行带有缓存的方法失败时,抛出此异常*/public Object execute(CacheCallback callback, int expiry) throws Exception {//从回调接口中获取keyString key = callback.getKey();logger.debug("cache key:{}", key);//如果key为空时,直接返回回调接口中的数值if (null == key) {Object value = callback.getValue();logger.debug("key is null,directly return execution result value[{}]", value);return value;}//从缓存服务中获取缓存CacheValue cacheValue = null;try {cacheValue = this.cacheProvider.getCache(key);logger.debug("fetch cache[key={},value={}]", key, cacheValue);} catch (Exception e) {Object value = callback.getValue();logger.warn("failure to fetch key[" + key + "] cache,directly return execution result value[" + value + "].caused by:" + e.getLocalizedMessage(), e);return value;}// 初始化缓存if (null == cacheValue) {Serializable initValue = callback.getValue();logger.debug("initialized cache value:{}", initValue);CacheValue initCacheValue = new CacheValue(initValue, new Date());setCache(key, initCacheValue, false);logger.debug("key[{}] cache is empty,return execution result value[{}] and added to cache[{}]", key, initValue, initCacheValue);return initValue;}// 缓存过期if (isExpired(cacheValue,expiry)) {try {Serializable newlValue = callback.getValue();logger.debug("new cached value:{}", newlValue);CacheValue newCacheValue = new CacheValue(newlValue, new Date());setCache(key, newCacheValue, true);logger.debug("key[{}] cache[{}] is expired,return re-execute result value[{}] and replaced by cache[{}]", key, cacheValue, newlValue, newCacheValue);return newlValue;} catch (Exception e) {logger.warn("re-execute failed when key[" + key + "] cache[" + cacheValue + "] is expired,return old cache value[" + cacheValue.getObject() + "].caused by:" + e.getLocalizedMessage(), e);if (!this.useOldCacheIfFail) {throw e;}}} else {if (logger.isDebugEnabled()) {logger.debug("key[{}] cache[{}] is valid,return cached value[{}]", key, cacheValue, cacheValue.getObject());}}return null;}/*** 设置缓存* @param key* @param cacheValue* @param isUpdated*/private void setCache(final String key, final CacheValue cacheValue, final boolean isUpdated) {//采用线程池来执行操作try {this.threadPool.execute(new Runnable() {@Overridepublic void run() {try {if (isUpdated) {CacheTemplate.this.cacheProvider.updateCache(key, cacheValue);} else {CacheTemplate.this.cacheProvider.addCache(key, cacheValue);}} catch (Exception e) {logger.warn("failure to set key[" + key + "] cache[" + cacheValue + "].caused by:" + e.getLocalizedMessage(), e);}}});} catch(RejectedExecutionException e){logger.warn("failure to set key[" + key + "] cache[" + cacheValue + "].caused by:thread pool is full", e);}}/*** 删除缓存.* * @param key key */public void deleteCache(String key){this.cacheProvider.deleteCache(key);}public CacheValue getCache(String key) throws Exception {return this.cacheProvider.getCache(key);}/*** 判断缓存中的时间是否过期* @param cacheValue* @param expiry* @return*/private boolean isExpired(CacheValue cacheValue,int expiry) {Date currentDate=new Date();Date expiredDate = DateUtils.addSeconds(cacheValue.getCreateDate(), expiry);return currentDate.after(expiredDate);}}

CacheValue.java

package cache;import java.io.Serializable;
import java.util.Date;/*** 保存到缓存中的实体.* @author linwei**/
public class CacheValue implements Serializable {private static final long serialVersionUID = 1L;/*** 缓存的内容*/private Serializable object;/*** 缓存的创建时间*/private Date createDate;public CacheValue(Serializable object, Date createDate) {this.object = object;this.createDate = createDate;}public Serializable getObject() {return this.object;}public void setObject(Serializable object) {this.object = object;}public Date getCreateDate() {return createDate;}public void setCreateDate(Date createDate) {this.createDate = createDate;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((createDate == null) ? 0 : createDate.hashCode());result = prime * result + ((object == null) ? 0 : object.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;CacheValue other = (CacheValue) obj;if (createDate == null) {if (other.createDate != null)return false;} else if (!createDate.equals(other.createDate))return false;if (object == null) {if (other.object != null)return false;} else if (!object.equals(other.object))return false;return true;}//    @Override
//  public String toString() {
//      StringBuilder builder = new StringBuilder();
//      builder.append("CacheValue [object=");
//      builder.append(this.object);
//      builder.append(", createDate=");
//      builder.append(DateFormatUtils.format(this.createDate, "yyyy-MM-dd hh:mm:ss"));
//      builder.append("]");
//      return builder.toString();
//  }}

XMMemcCacheProvider.java

package cache;import java.io.IOException;
import java.util.Arrays;import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.MemcachedClientBuilder;
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
import net.rubyeye.xmemcached.utils.AddrUtil;import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/*** 基于memcached的实现.使用的Client是Memcached-Java-Client.* @author linwei**/
public class XMMemcCacheProvider implements CacheProvider {//内部静态类public static class Config {/*** 服务地址*/private String servers;/*** 服务器负载量*/private int[] weights;/*** 操作超时,单位:毫秒*/private long opTimeout = MemcachedClient.DEFAULT_OP_TIMEOUT;/*** 连接超时,单位:毫秒*/private int connectTimeout = MemcachedClient.DEFAULT_CONNECT_TIMEOUT;public String getServers() {return this.servers;}public void setServers(String servers) {this.servers = servers;}public int[] getWeights() {return this.weights;}public void setWeights(int... weights) {this.weights = weights;}public long getOpTimeout() {return this.opTimeout;}public void setOpTimeout(long opTimeout) {this.opTimeout = opTimeout;}public int getConnectTimeout() {return this.connectTimeout;}public void setConnectTimeout(int connectTimeout) {this.connectTimeout = connectTimeout;}@Overridepublic String toString() {return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);}}private final static Logger logger = LoggerFactory.getLogger(XMMemcCacheProvider.class);private MemcachedClient memcachedClient;private int expiry = Integer.MAX_VALUE;public XMMemcCacheProvider(Config config) {logger.debug("loaded Config[{}]", config);String[] servers = config.getServers().split(",");int[] weights = config.getWeights();if (ArrayUtils.isEmpty(weights)) {weights = new int[servers.length];Arrays.fill(weights, 1);}String serverList = formatServers(servers);if (logger.isDebugEnabled()) {logger.debug("servers:{}", serverList);logger.debug("weights:{}", Arrays.toString(weights));}MemcachedClientBuilder builder = new XMemcachedClientBuilder(AddrUtil.getAddresses(serverList), weights);builder.setConnectTimeout(config.getConnectTimeout());builder.setOpTimeout(config.getOpTimeout());try {this.memcachedClient = builder.build();} catch (IOException e) {throw new RuntimeException("failure to build MemcachedClient", e);}}private String formatServers(String[] input) {String[] array = new String[input.length];for (int i = 0; i < array.length; i++) {array[i] = input[i].trim();}return StringUtils.join(array, " ");}@Overridepublic CacheValue getCache(String key) throws Exception {CacheValue value = (CacheValue) this.memcachedClient.get(key);logger.debug("getted cache[{}] by key[{}]", value, key);return value;}@Overridepublic void addCache(String key, CacheValue value) {setCache(key, value);logger.debug("added key[{}] cache[{}]", key, value);}@Overridepublic void updateCache(String key, CacheValue value) {setCache(key, value);logger.debug("updated key[{}] cache[{}]", key, value);}private void setCache(String key, CacheValue value) {try {this.memcachedClient.set(key, this.expiry, value);} catch (Exception e) {throw new RuntimeException(e);}}@Overridepublic void deleteCache(String key) {try {this.memcachedClient.delete(key);logger.debug("deleted key[{}] cache", key);} catch (Exception e) {throw new RuntimeException(e);}}}

三。 进行测试。

CacheTest.java

package test;import java.io.Serializable;
import java.util.Date;import cache.CacheCallback;
import cache.CacheTemplate;
import cache.CacheValue;
import cache.XMMemcCacheProvider;
import cache.XMMemcCacheProvider.Config;public class CacheTest {private final static String servers = "127.0.0.1:11103";public static void main(String[] args) throws Exception {
//      addCache();getCache();}private static void addCache() throws Exception {Config config = new Config();config.setServers(servers);XMMemcCacheProvider xmMemcCacheProvider = new XMMemcCacheProvider(config);CacheTemplate cacheTemplate = new CacheTemplate(xmMemcCacheProvider);cacheTemplate.execute(new CacheCallback(){@Overridepublic String getKey() {return "alanlin";}@Overridepublic Serializable getValue() throws Exception {return "testlin" + new Date();}});System.err.println("addCache over.");}private static void getCache() throws Exception {Config config = new Config();config.setServers(servers);XMMemcCacheProvider xmMemcCacheProvider = new XMMemcCacheProvider(config);CacheTemplate cacheTemplate = new CacheTemplate(xmMemcCacheProvider);CacheValue cacheValue = cacheTemplate.getCache("alanlin");System.err.println("value is " + cacheValue.getObject());System.err.println("getCache over.");}}

使用MemCache进行相关缓存的保存处理相关推荐

  1. 使用Nginx+Memcache做页面缓存

    前言 官方商城改版之后,为了提升动态页面的访问速度,对商城的一些页面进行了缓存,使其在一定时间之内避免了重复的查询和编译. 原理 主要使用了 nginx 的 memcached_module 模块,直 ...

  2. memcache的分布式缓存问题

    memcache的分布式缓存问题 memcache是优异的缓存解决方案,很多项目都有使用. memcache服务本身并不具备分布式缓存的能力,它提供的就是对{key, value}对的访问能力,分布式 ...

  3. ehcache memcache redis 三大缓存

    2019独角兽企业重金招聘Python工程师标准>>> 最近项目组有用到这三个缓存,去各自的官方看了下,觉得还真的各有千秋!今天特意归纳下各个缓存的优缺点,仅供参考!  Ehcach ...

  4. NoSQL分类及ehcache memcache redis 三大缓存的对比

    NoSQL分类 由于NoSQL中没有像传统数据库那样定义数据的组织方式为关系型的,所以只要内部的数据组织采用了非关系型的方式,就可以称之为NoSQL数据库. 目前,可以将众多的NoSQL数据库按照内部 ...

  5. ehcache memcache redis 三大缓存男高音

    2019独角兽企业重金招聘Python工程师标准>>> 最近项目组有用到这三个缓存,去各自的官方看了下,觉得还真的各有千秋!今天特意归纳下各个缓存的优缺点,仅供参考!  Ehcach ...

  6. linux自学笔记--memcache和varnish缓存服务器

    1.memcached: kv结构,存储于内存之中,可减小数据库访问压力,也可做为session服务器使用 (1)常用命令 -u 指定用户    -m 指定内存大小 -d start|restart| ...

  7. 一种基于memcache或redis缓存架构的验证码

    本文出处:http://blog.csdn.net/chaijunkun/article/details/8996794,转载请注明.由于本人不定期会整理相关博文,会对相应内容作出完善.因此强烈建议在 ...

  8. 使用memcache做web缓存

    为什么80%的码农都做不了架构师?>>>    下载: memcached server [密码: vTI8, 安装启动和调用, 内部有说明] 下载: python-memcache ...

  9. iPhone/iOS图片相关(读取、保存、绘制、其它相关)

    一.读取图片 1.从资源(resource)读取 [cpp] view plaincopyprint? UIImage* image=[UIImage imageNamed:@"1.jpg& ...

最新文章

  1. mysql存储家庭成员信息_家谱管理系统的设计与实现(MyEclipse,MySQL)
  2. sphinx是支持结果聚类的
  3. 数据分析 python 用途-利用Python数据分析可以实现些什么功能呢?
  4. 【笔记】windows10安装linux双系统教程(可能是现今最简单方法)
  5. Blender文档翻译:Operators tutorial(操作教程)
  6. qt5 交叉编译webkit_Qtwebkit配置,设置交叉编译环境 - croop520的专栏 - 博客频道 - CSDN.NET...
  7. CVPR2017精彩论文解读:用于生物医学图像分析的精细调节卷积神经网络
  8. 模拟利器Mockito
  9. android切换输入法工具类
  10. 反恐精英ol永恒python厉害吗_【CS】Python高阶
  11. item_search_img - 拍立淘搜索淘宝商品(淘宝API)
  12. code force 449 div2 C. Nephren gives a riddle
  13. 【css技巧】CSS filter的神奇用法 | 褪色|融合效果等
  14. 家庭组网方案研究(2):路由器和光猫上的连接方式
  15. Cocos2d-x的学习之旅(七)更新函数Update
  16. MicroPython-On-ESP8266——WIFI与网络
  17. java多线程归并排序_并行计算实验-串、并行排序算法
  18. 视频营销:一款产品如何设计多种赚钱方式
  19. 21天精通python电子版_小白21天精通Python是如何做到的?
  20. drf框架使用之 路飞学城(第一天)

热门文章

  1. java - What is a fat JAR? - Stack Overflow
  2. web 页面table 斜线效果 跨越多行和 多列
  3. Project Euler
  4. [Web开发] 如何改变IE滚动条的颜色
  5. Delphi 与 DirectX 之 DelphiX(93): TDIB.DrawDarken();
  6. python 2.7下的正则将中文分隔符去掉
  7. 高品质低成本 佳能发布4款加墨式打印新品
  8. eclipse fat jar 打包插件
  9. From NSURLConnection to NSURLSession
  10. linux学习笔记十一(LVM基础)