欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

review引發(fā)的有關于單例模式的思考

 更新時間:2013年04月02日 17:23:38   作者:  
一次代碼調試中發(fā)現一個情況,即我在查看memcached的connection時,發(fā)現總是維持在100來個左右,當然這看似沒什么問題,因為memcached默認connection有1024個。

一次代碼調試中發(fā)現一個情況,即我在查看memcached的connection時,發(fā)現總是維持在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多個連接?

上面這個寫法真的能保證只產生一個連接?很顯然是不能,為什么?多線程并發(fā)!問題就出在這里,當有多個線程同時進入createClient()方法時,而且剛好都判斷為memcachedClient為null,這時候就產生了多個連接。哈,問題找到了。

改進:

復制代碼 代碼如下:

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

這樣就ok了,改動很簡單。程序是沒有問題了,而且也能保證只有一個連接。

不過拋開這個問題,我們可以繼續(xù)就如何解決單例模式下的并發(fā)問題深入思考一下。

我總結一下,要解決單例模式在并發(fā)下的問題,大概有三種方式:

1. 不使用延遲實例化,而是用提前實例化。

即程序改寫為:

復制代碼 代碼如下:

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

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

這樣做時,jvm在加載類時就立馬創(chuàng)建了該實例,所以這樣做的前提是,創(chuàng)建該實例的負擔不大,我不比過多的考慮性能,并且我們確認該實例是一定會用到的。其實我前面的代碼也完全可以使用這個方式:

復制代碼 代碼如下:

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的開銷是很大的,會嚴重影響性能,所以用這個的前提是,你確認不會經常調用這個方法,或者你創(chuàng)建這個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;
}
}

 

相關文章

  • Java消息隊列RabbitMQ之消息模式詳解

    Java消息隊列RabbitMQ之消息模式詳解

    這篇文章主要介紹了Java消息隊列RabbitMQ之消息模式詳解,RabbitMQ提供了一種qos(服務質量保證)功能,即在非自動確認消息的前提下,如果一定數目的消息(通過基于Consumer或者Channel設置Qos的值)未被確認前,不進行消費新的消息,需要的朋友可以參考下
    2023-07-07
  • JSP代碼實現 金字塔(倒置)示例

    JSP代碼實現 金字塔(倒置)示例

    這篇文章主要介紹了JSP代碼實現 金字塔(倒置)示例,需要的朋友可以參考下
    2014-02-02
  • SpringMVC中的HandlerMapping和HandlerAdapter詳解

    SpringMVC中的HandlerMapping和HandlerAdapter詳解

    這篇文章主要介紹了SpringMVC中的HandlerMapping和HandlerAdapter詳解,在Spring MVC中,HandlerMapping(處理器映射器)用于確定請求處理器對象,請求處理器可以是任何對象,只要它們使用了@Controller注解或注解@RequestMapping,需要的朋友可以參考下
    2023-08-08
  • Java SSL與TLS客戶端證書配置方式

    Java SSL與TLS客戶端證書配置方式

    這篇文章主要介紹了Java SSL與TLS客戶端證書配置方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Nginx啟用壓縮及開啟gzip 壓縮的方法

    Nginx啟用壓縮及開啟gzip 壓縮的方法

    這篇文章主要介紹了Nginx啟用壓縮及開啟gzip 壓縮的方法,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-08-08
  • spring boot項目application.properties文件存放及使用介紹

    spring boot項目application.properties文件存放及使用介紹

    這篇文章主要介紹了spring boot項目application.properties文件存放及使用介紹,我們的application.properties文件中會有很多敏感信息,大家在使用過程中要多加小心
    2021-06-06
  • java如何獲取兩個List集合之間的交集、差集、并集

    java如何獲取兩個List集合之間的交集、差集、并集

    在日常開發(fā)中經常會遇到對2個集合的操作,例如2個集合之間取相同的元素(交集),2個集合之間取不相同的元素(差集)等等,這篇文章主要給大家介紹了關于java如何獲取兩個List集合之間的交集、差集、并集的相關資料,需要的朋友可以參考下
    2024-02-02
  • SpringBoot集成Redisson實現分布式鎖的方法示例

    SpringBoot集成Redisson實現分布式鎖的方法示例

    這篇文章主要介紹了SpringBoot集成Redisson實現分布式鎖的方法示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-10-10
  • Spring Boot Security配置教程

    Spring Boot Security配置教程

    在本文里我們給大家分享了關于Spring Boot Security配置的相關步驟以及注意要點,需要的朋友們跟著操作下。
    2019-05-05
  • 如何使用Java生成PDF文檔詳解

    如何使用Java生成PDF文檔詳解

    這篇文章主要給大家介紹了關于如何使用Java生成PDF文檔的相關資料,PDF是可移植文檔格式,是一種電子文件格式,具有許多其他電子文檔格式無法相比的優(yōu)點,需要的朋友可以參考下
    2023-07-07

最新評論