轉:單例模式(序列化)

來源:互聯網
上載者:User

如果你序列化一個單例類,然後兩次重構它,那麼你就會得到那個單例類的兩個執行個體,除非你實現readResolve()方法,像下面這樣:
例1 一個可序列化的單例類

Java代碼
import
org.apache.log4j.Logger;   
     
public class Singleton implements java.io.Serializable
{   
   public static Singleton
INSTANCE = new
Singleton();   
     
   protected Singleton()
{   
     
// Exists only to thwart
instantiation.    
   } 

   
   private Object readResolve()
{   
           
return
INSTANCE;    
   }   
}   

上面的單例類實現從readResolve()方法中返回一個唯一的執行個體;這樣無論Singleton類何時被重構,它都只會返回那個相同的單例類執行個體。

例2測試了例1 的單例類

 

例2 測試一個可序列化的單例類

Java代碼
import
java.io.*;   
import
org.apache.log4j.Logger;   
import
junit.framework.Assert;   
import
junit.framework.TestCase;   
     
public class SingletonTest extends TestCase
{   
   private Singleton sone = null,
stwo =
null;   
   private static Logger logger =
Logger.getRootLogger();   
     
   public SingletonTest(String
name) {   
     
super(name);   
   
}   

   public void setUp()
{   
      
sone =
Singleton.INSTANCE;   
      
stwo =
Singleton.INSTANCE;   
   
}   

   public void
testSerialize()
{   
      
logger.info("testing singleton
serialization...");    
      
writeSingleton();   
      
Singleton s1 =
readSingleton();   
      
Singleton s2 =
readSingleton();   
      
Assert.assertEquals(true, s1 ==
s2);[/b]   

  
}   

   private void
writeSingleton()
{   
     
try {   
         
FileOutputStream fos = new
FileOutputStream("serializedSingleton");   
         
ObjectOutputStream oos = new
ObjectOutputStream(fos);   
         
Singleton s =
Singleton.INSTANCE;   
     
         
oos.writeObject(Singleton.INSTANCE);   
         
oos.flush();   
      
}catch(NotSerializableException se)
{   
         
logger.fatal("Not Serializable Exception: " +
se.getMessage());    
     
 }catch(IOException iox)
{   
         
logger.fatal("IO Exception: " +
iox.getMessage());    
     
 }   
   
}   

   private Singleton
readSingleton()
{   
      
Singleton s =
null;   
     
     
try {   
         
FileInputStream fis = new
FileInputStream("serializedSingleton");   
         
ObjectInputStream ois = new
ObjectInputStream(fis);   
         
s =
(Singleton)ois.readObject();   
      
}catch(ClassNotFoundException cnf)
{   
         
logger.fatal("Class Not Found Exception: " +
cnf.getMessage());   
      
}catch(NotSerializableException se)
{   
         
logger.fatal("Not Serializable Exception: " +
se.getMessage());   
      
}catch(IOException iox)
{   
         
logger.fatal("IO Exception: " +
iox.getMessage());   
      
}   
     
return
s;   
   
}   

   public void
testUnique()
{   
      
logger.info("testing singleton
uniqueness...");   
      
Singleton another = new
Singleton();   
     
      
logger.info("checking singletons for
equality");   
      
Assert.assertEquals(true, sone ==
stwo);   
   
}   
}   

   
前面這個測試案例序列化例1
中的單例類,並且兩次重構它。然後這個測試案例檢查看是否被重構的單例類執行個體是同一個對象。下面是測試案例的輸出:

Java代碼
Buildfile:
build.xml   
     
init:   
     
[echo] Build 20030422 (22-04-2003
11:32)   
     
compile:   
     
run-test-text:   
     
[java] .INFO main: testing singleton
serialization...   
     
[java] .INFO main: testing singleton
uniqueness...   
     
[java] INFO main: checking singletons for
equality   
     
     
[java] Time:
0.1   
     
     
[java] OK (2
tests)   

單例模式結束語

   
單例模式簡單卻容易讓人迷惑,特別是對於Java的開發人員來說。在這篇文章中,作者示範了Java開發人員在顧及多線程、類載入器和序列化情況如何?單例模式。作者也展示了你怎樣才能實現一個單例類的註冊表,以便能夠在運行期指定單例類。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.