麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > Java > 正文

review引發的有關于單例模式的思考

2019-11-26 16:12:48
字體:
來源:轉載
供稿:網友

一次代碼調試中發現一個情況,即我在查看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;
}
}

這樣做時,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了。當然這是極端情況了,但是為了代碼的健壯,可以再改為:

復制代碼 代碼如下:

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;
}
}

 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 精品国产91久久久久 | 国产一级一国产一级毛片 | 欧美jizzhd极品欧美 | av电影免费观看 | 一区二区久久精品66国产精品 | 亚洲小视频在线 | 精品国产九九九 | 欧美性生交大片 | 国产精品视频一区二区三区四 | 黄色免费影片 | 羞羞色网站 | 91九色视频在线播放 | 国产成人综合在线观看 | 欧美性videofree精品 | 91精品国产777在线观看 | 看免费的毛片 | 综合网天天射 | 男女羞羞在线观看 | 在线播放黄色网址 | 青草久久久久 | 黄色毛片免费视频 | 99在线在线视频免费视频观看 | 精品一区二区三区中文字幕老牛 | 久久久裸体视频 | 草莓福利视频在线观看 | 亚洲第一成人在线 | 成人午夜精品 | 亚洲综合一区在线观看 | 日韩在线播放第一页 | 国产在线观看91一区二区三区 | av色先锋 | 黄色片视频观看 | 国产亚洲精久久久久久蜜臀 | 99视频有精品 | 黄色免费电影网址 | 欧美成人一区免费视频 | 一级免费看片 | 久久精品一二三区白丝高潮 | 日韩视频在线观看免费视频 | 国产成人精品免费视频大全最热 | 爽爽淫人综合网网站 |