單例模式,個人理解就是,使用了這個模式,可以保證一個類只生成唯一的實例對象。就是在整個程序中,這個類只存在一個實例對象。
GoF對單例模式的定義:保證一個類,只有一個實例存在,同時提供能對該實例加以訪問的全局訪問方法。
客戶端的代碼用來測試,獲取到的實例只有一個。直接上代碼。
1 public class MainClass { 2 public static void main(String[] args) { 3 Person person1=Person.getPerson();//獲取Person對象 4 Person person2=Person.getPerson();//獲取Person對象 5 person1.setName("Tom"); 6 person2.setName("WhiteTaken");//如果兩個獲取的到的對象的實例,是同一實例,那么打印出來的名字應該是一樣的。 7 System.out.println(person1.getName()); 8 System.out.println(person2.getName()); 9 } 10 }
如果不是單例模式,而僅僅是創建了幾個對象 ,那么兩次打印的結果,將會是兩個不同的名字。
而單例模式的情況,獲取的到的是同一個對象,那么兩次打印的結果,將是第二次賦值的結果。
單例測試結果如下。
好,上面是測試結果,那么單例模式是怎么實現的呢。
我學習到的三種單例模式的創建方法。
1.直接用final方式創建。只要類執行,就會創建這樣一個對象。
代碼如下。
1 public class Person { 2 private String name; 3 public static final Person perSon= new Person();//注意此處的final 4 public String getName() { 5 return name; 6 } 7 8 public void setName(String name) { 9 this.name = name; 10 } 11 //構造函數私有化 12 private Person(){ 13 14 } 15 //獲取對象的方法,final實現 16 public static Person getPerson(){ 17 return perSon; 18 } 19 }
通過final關鍵字,保證perSon只被賦值一次,即值生成一次對象。
2.第二種方式,通過在獲取對象的方法中判斷person是否為null,如果不存在,則實例化person,如果存在,則直接返回person實例。
1 public class Person2 { 2 private String name; 3 private static Person2 perSon; 4 public String getName() { 5 return name; 6 } 7 public void setName(String name) { 8 this.name = name; 9 } 10 //構造函數私有化 11 private Person2(){ 12 13 } 14 //獲取對象的方法,單線程模式可用 15 public static Person2 getPerson(){ 16 if(perSon==null){ 17 return perSon=new Person2(); 18 } 19 return perSon; 20 } 21 }
以上方法是實現單例模式的第二種方法,但是此種方法有一個天然的劣勢,就是只適合單線程開發。
多線程的話,如果兩個線程同時訪問這個方法的話,返回的person對象可能會出現不一樣的情況 ,那就不是單例了。
如果使用同步方法的話(synchronized),多線程的情況下會造成線程等待,影響效率。
3.第三種方式是通過雙重檢查的方式實現單例。
雙重判斷,通過兩次判斷null,能夠確保在多線程下,只生成一個單例。
1 public class Person4 { 2 private String name; 3 private static Person4 perSon; 4 public String getName() { 5 return name; 6 } 7 8 public void setName(String name) { 9 this.name = name; 10 } 11 //構造函數私有化 12 private Person4(){ 13 14 } 15 //獲取對象的方法,雙重檢查 16 public static Person4 getPerson(){ 17 if(perSon==null){ 18 synchronized (Person4.class) { 19 if(perSon==null){ 20 return perSon=new Person4(); 21 } 22 } 23 } 24 return perSon; 25 } 26 }
這樣就完成單例模式的簡單應用。
要想達到學以致用,真的很難,工作久了,很多東西都忘了。。。單例模式寫的一個小例子,加強理解。
需要注意:只創建了一次對象。
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Console.WriteLine("================測試單例模式=========begin======"); 6 Test tst = GetAllTest.GetTest(); 7 tst.TestPrint(); 8 Test tst2 = GetAllTest.GetTest(); 9 tst2.TestPrint(); 10 Console.WriteLine("================測試單例模式=========end========"); 11 Console.Read(); 12 } 13 } 14 15 16 class Test 17 { 18 public Test(){} 19 public void TestPrint() 20 { 21 Console.WriteLine("單例模式打印結果"); 22 } 23 } 24 25 class GetAllTest 26 { 27 private static Test ts; 28 public static Test GetTest() 29 { 30 if(ts == null) 31 { 32 Console.WriteLine("創建Test對象過程"); 33 ts = new Test(); 34 } 35 36 return ts; 37 } 38 }
打印結果:
好好努力,提高自己!!!
文章列表