前言:
學習面向對象程序設計的朋友應該知道,我們大多數情況下通過 new 操作來實例化對象的。對於一些僅需要一次初始化的對象來說,頻繁的new操作無疑會過多浪費內存空間。基於此,單例模式便應運而生了。所謂單例,即"一次初始化,多次操作"。那么本文就介紹一下自己封裝一個支持單例的類的主要步驟。
實現單例的3個要點:
·靜態化實例;
·將構造方法封裝為private;
·對外提供一個公開的getInstance()方法。
代碼實現:
package com.modelDesign.instance; public class Person { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } private Person(){ } private static Person pp=new Person(); public static Person getInstance(){ return pp; } }
客戶端測試程序:
package com.modelDesign.instance; public class TestPerson { public static void main(String[] args) { Person p1 = Person.getInstance(); p1.setName("Jack"); Person p2 = Person.getInstance(); System.out.println("是否單例:"+(p1==p2)); System.out.println(p2.getName()); } }
測試結果:
補充:
當你設計的應用涉及到多線程時,上面的代碼還是有瑕疵的。由於線程與線程之間的沖突,很可能會造成多次初始化。由此,我們引入多線程的鎖——Lock加以解決。
適應多線程的單例實現:
package com.modelDesign.instance; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class InstanceSuper { private static InstanceSuper instance; private static Lock lock=new ReentrantLock(); private InstanceSuper() { } public static InstanceSuper getInstance(){ if(instance==null){ lock.lock(); if(instance==null){ instance = new InstanceSuper(); } lock.unlock(); } return instance; } }
注意:測試類不要包含在單例類中,因為同一個類中私有的構造方法同樣可以被其他方法調用,也就是說在main()函數進行new操作時不會報錯!!