review引发的有关于单例模式的思考

2016-02-19 10:49 1 1 收藏

生活已是百般艰难,为何不努力一点。下面图老师就给大家分享review引发的有关于单例模式的思考,希望可以让热爱学习的朋友们体会到设计的小小的乐趣。

【 tulaoshi.com - 编程语言 】

一次代码调试中发现一个情况,即我在查看memcached的connection时,发现总是维持在100来个左右,当然这看似没什么问题,因为memcached默认connection有1024个。但是我想的是为什么会有100来个,因为我的memcachedclient的产生采用的是单例模式我定义了一个memcachedClientFactory类,主要代码如下:

代码如下:

MemcachedClientFactory{
private MemcachedConnectionBuilder memcachedConnectionBuilder;
private String servers;
private static MemcachedClient memcachedClient;

private MemcachedClientFactory(){
}

private MemcachedClientFactory(MemcachedConnectionBuilder memcachedConnectionBuilder, String servers){
 this. memcachedConnectionBuilder= memcachedConnectionBuilder;
 this.servers=servers;
 }

public static MemcachedClient createClient(){
if(memcachedClient==null){
this.memcahcedClien= new MemcachedClient(memcachedConnectionBuilder.build(),AddrUtil.get(servers));
}
 return this.memcahcedClient;
}
}
}

回到最初的问题,为什么会有100多个连接?

上面这个写法真的能保证只产生一个连接?很显然是不能,为什么?多线程并发!问题就出在这里,当有多个线程同时进入createClient()方法时,而且刚好都判断为memcachedClient为null,这时候就产生了多个连接。哈,问题找到了。

改进:

代码如下:

public static synchronizd MemcachedClient createClient(){
 if(memcachedClient==null){
this.memcahcedClien=  new
MemcachedClient(memcachedConnectionBuilder.build(),AddrUtil.get(servers));
}
 return this.memcahcedClient;
}

这样就ok了,改动很简单。程序是没有问题了,而且也能保证只有一个连接。

不过抛开这个问题,我们可以继续就如何解决单例模式下的并发问题深入思考一下。

我总结一下,要解决单例模式在并发下的问题,大概有三种方式:

1. 不使用延迟实例化,而是用提前实例化。

即程序改写为:

代码如下:

Public Class Singleton{
private static Singleton instance=new Singleton();
private Singleton(){};

public static Singleton getInstance(){
   return instance;
}
}

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

这样做时,jvm在加载类时就立马创建了该实例,所以这样做的前提是,创建该实例的负担不大,我不比过多的考虑性能,并且我们确认该实例是一定会用到的。其实我前面的代码也完全可以使用这个方式:

代码如下:

MemcachedClientFactory{
private MemcachedConnectionBuilder memcachedConnectionBuilder;
private String servers;
private static MemcachedClient memcachedClien= new
MemcachedClient(memcachedConnectionBuilder.build(),AddrUtil.get(servers));

private MemcachedClientFactory(){
}

private MemcachedClientFactory(MemcachedConnectionBuilder memcachedConnectionBuilder, String servers){
 this. memcachedConnectionBuilder= memcachedConnectionBuilder;
 this.servers=servers;
 }

public static MemcachedClient createClient(){
 return this.memcahcedClient;
}
}
}

不过,看上去似乎没有问题,但是有隐患,即一旦有人不小心调用了memcachedClient.shutdown()方法,那整个程序就无法再生出新的memcachedClient了。当然这是极端情况了,但是为了代码的健壮,可以再改为:

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

代码如下:

public static MemcachedClient createClient(){
if(memcachedClient==null){
this.memcahcedClien= new MemcachedClient(memcachedConnectionBuilder.build(),AddrUtil.get(servers));
}
return this.memcahcedClient;
}

2.  就是使用synchronized关键字。

这么做可以保证同步问题,但是我们知道使用synchronized的开销是很大的,会严重影响性能,所以用这个的前提是,你确认不会经常调用这个方法,或者你创建这个instance的开销不会特别大。是否还可以改进,看 下面。

3. 使用“双重检查加锁“,在getInstance中见识使用同步

代码如下:

public Class Singleton{
private volatile static Singleton instance;

private Singleton(){};
public static Singleton getInstance(){
 if(instance==null){
  synchronized (Singleton.class){
 if(instance==null){
 instance=new Singleton();
}
}

}
return instance;
}
}

来源:https://www.tulaoshi.com/n/20160219/1595858.html

延伸阅读
标签: Web开发
最近在处理Qzone黄钻图标更新时,想起近期对业务图标进行优化所遇到的一些问题,把思绪收拾起来和大家一共探讨,欢迎多方声音。 在实际工作中,图标类的应用非常广泛,如同数组般的等级图标更显其特殊性。下面要共同探讨的两个方向,以什么方式实现及怎么更好在贴近项目实际更好地实现并供应用。 假设:业务的用户等级共有10个,加上大小2...
本期《ideas》主要就Metro UI所带来的趋势进行多方面的探讨甚至不同声音的争论,以及某汽车网站的创意分享。 本期作者:Dorishu、Vincentcai、Omegazhao 2.设计是O关于设计趋势的思考 设计是O,O是什么,O是Origin原点,《生活大爆炸》的片头就是一切原点的起源,而人类发展史就是一个越滚越大的原点,总是发现有一个不断循环的规律,艺...
1. 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方。与C++不同,Java自动治理栈和堆,程序员不能直接地设置栈或堆。 !-- frame contents -- !-- /frame contents -- 2. 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。另外,...
标签: Web开发
字体的处理在网页设计中无论怎么强调也不为过,毕竟网页使用来传递信息的,而最经典最直接的信息传递方式就是文字,所以,了解一点字体的基本知识对于设计来说还是非常重要的。 中文和英文的最大区别就是中文是方块字,英文是拼音文字,这对字体的处理的影响是巨大的。看看下面的图示就会发现,英文字体里的那些变化在中文字体里都弱...
有些不含活性菌的产品也会在标签上生成含有益生菌,或者标注的益生菌含量比实际要高。2013年,独立调查机构所做的调查发现19种益生菌营养品中,有5种实际含有的微生物比声称的要少。有些产品的益生菌含量仅有成分表上的56%,最少的只有表上声称的16%。 有关于益生菌的几个认识误区 有关于益生菌的几个认识误区 食物和营...

经验教程

41

收藏

51
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部