使用Spymemcached作为Memcached客户端,因为提供的接口并不算复杂,打算直接写一个Util类供其他模块调用。以Set方法为例:
- 每次调用方法都创建客户端实例。这种方式每次都要调用都要创建、销毁实例,在操作比较频繁的情况下存在一定的开销
// Set方式保存数据
public void set(String key, int exp, Object o)
throws IOException, InterruptedException, ExecutionException {
MemcachedClient memcachedClient = new MemcachedClient(
new BinaryConnectionFactory(), AddrUtil.getAddresses(host + ":" + port)
);
memcachedClient.set(key, exp, o);
memcachedClient.shutdown();
}
- 所有方法共用一个客户端实例。这种方法可以减少创建实例和链接,但是在请求不太频繁的时段可能会因为没有销毁实例而一直占用着Memcached的链接。
private static MemcachedClient memcachedClient = null;
static {
try {
memcachedClient = new MemcachedClient(
new BinaryConnectionFactory(), AddrUtil.getAddresses(host + ":" + port)
);
} catch (IOException ioe) {
log.error(ioe.getMessage(), ioe);
}
}
// Set方式保存数据
public void set(String key, int exp, Object o)
throws IOException, InterruptedException, ExecutionException {
memcachedClient.set(key, exp, o);
}
所以,请问有什么方法可以缓存Memcached的客户端实例,在需要的时候直接到缓存中获取或者创建实例,如果长期没有调用的话,则销毁该实例,直到下次调用。最好能做到线程安全。
所有方法共用一个客户端实例。这种方法可以减少创建实例和链接,但是在请求不太频繁的时段可能会因为没有销毁实例而一直占用着Memcached的链接。
这个你想的太多了,占用的这点资源可以忽略不计了。当然如果你非得要达到你的目的,可以产看下JDK里CachedThreadPool的实现。
newCachedThreadPool
public static ExecutorService newCachedThreadPool() 创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。对于执行很多短期异步任务的程序而言,这些线程池通常可提高程序性能。调用 execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。因此,长时间保持空闲的线程池不会使用任何资源。注意,可以使用 ThreadPoolExecutor 构造方法创建具有类似属性但细节不同(例如超时参数)的线程池。 返回: 新创建的线程池
“但是在请求不太频繁的时段可能会因为没有销毁实例而一直占用着Memcached的链接。”
这又如何?你想太多了,负责任的告诉你,就用这个方法,生产环境下,100w DAU,2000w用户,完全没任何问题。