關於單例模式的心結


  今天重構公司的代碼,看到有一個單例的對象,在整個系統中到處都存在調用它的身影,因為我們這個項目會在應用服務器(server)第一次啟動的時候加載數據庫中的代碼表(為什么要先加載,因為這個項目采用的是C/S模式,利用remoting進行通信,在客戶端啟動的時候會多次獲取代碼表中的不同數據。)

 1  public class CodeTableSingleTon
 2 {
 3     ///防止外部被實例化
 4    private CodeTableSingleTon(){
 5        //進行數據的讀取操作
 6    }
 7    //
 8   private static readonly object _lock=new object();
 9 
10   private static CodeTableSingleTon _instance;
11   
12    public static CodeTableSingleTon Instance
13   {
14   get
15    {
16     if(_instance==null)
17      {
18          lock(_lock){
19             if(_instance==null) 
20             {
21             _instance=new CodeTableSingleTon();   
22             }
23           }
24     }
25   return _instance;
26    }
27 }
28 
29 
30 }

上面代碼就是項目的實現方式,我了解過單例模式,單例模式是控制對象的創建,可以實現延遲加載,只有在對象被調用的時候才會真正的執行對象的實例化,可以在一定程度上減少內存的耗用(是在不使用該對象的情況下)。既然在整個系統中只有一個該對象, 因為項目是采用多線程處理客戶端的請求,所以每個線程都可以獲取到該對象進行數據的獲取,系統運行也沒發現 由於這個對象的創建或者其他問題。

 

  但是我深入的想了一下,如果我在單例對象中加入一個計數器,表示單例對象被調用的次數,那么這個對象內部的屬性 可能會同時被多個線程進行更新。

 1 public class SingleTon
 2 {
 3 
 4   private static SingleTon _instance;
 5   private static readonly object _lock=new object();
 6   private SingleTon(){} //私有的構造函數 確保該實例不能在外部直接通過new實例化
 7   public static long totalNum=0;//初始化計數器默認值為0
 8   public static SingleTon Instance
 9   {
10   get  
11   {
12     if(_instance==null)
13       {
14        lock(_lock)
15        {
16           if(_instance==null)
17           {
18           _instance=new SingleTon();
19           }
20        }
21       }
22       totalNum=totalNum+1; //每次調用計數器都會加1
//Consle.WriteLine(totalNum);
23 return _instance; 24 } 25 } 26 }

 

我嘗試開啟了多個線程來執行這段代碼,沒有發現totalNum的值存在由於多個線程的調用出現重復數據輸出的情況。那么我心里一直在糾結一個事,就是說假如兩個線程都在同一時間獲取到了這個單例對象,那么都會依次執行計數器加1,如果說兩個線程執行到totalNum=totalNum+1 這句話的時候不是在同時的,那么不會出現問題。

如果這兩個線程中了彩票了,同時執行了totalNum=totalNum+1,那么就會導致計數器少算了一次調用嗎?我在測試,開啟了100個線程,沒有發現重復的值存在,難道我的理解是錯誤的嗎?我記得在多線程下操作同一數據是會出現這個問題的?不知道這個對單例模式是否適用呢?糾結糾結,求准確的回復

 

如果單例的方式存在問題,那么采用靜態字段也會出現這個問題,就無法統計計數器了。mygod  腦袋要炸了

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM