一、單例模式
是Java多種設計模式中較為常用的一種,在它的核心結構中只包含了一個稱為單例的特殊類別。透過單例模式可以保證系統中,應用此模式的類別只有一個實例。
二、模式需求
1、自己的建構方法必須私有化
2、類別的內部自己創造一個自己唯一的實例
#3 、要提供一個公開的靜態方法供其他物件取得該實例
三、幾種實作方式
#餓漢式
public class Simple { private static Simple simple = new Simple(); private Simple() { } public static Simple getInstance() { return simple; } }
這種實作方式在類別載入時進行實例化,沒有延遲加載,是線程安全的。
懶漢式
public class Slacker { private static volatile Slacker slacker = null; private Slacker() { } /** * 最简单的懒汉式实现 * @return */ public static Slacker getInstance() { if(slacker == null) { slacker = new Slacker(); } return slacker; } }
這種實作方式是最基本的實現,最大的問題是不支援多線程,並發存取方法會獲得不只一個實例,所以嚴格來講不是單例模式。
public class Slacker { //volatile关键字的作用 //1、保证内存可见性:保证每个线程访问volatile修饰的共享变量时获取到的都是最新的。 //2、防止指令重排序--通过内存屏障实现 private static volatile Slacker slacker = null; private Slacker() { } /** * 加synchronized关键字解决线程同步问题 * @return */ public static synchronized Slacker getInstanceSync() { if(slacker == null) { slacker = new Slacker(); } return slacker; } }
這種透過在方法上加synchronized鎖定實現的方式,可以解決執行緒並發存取的問題,實作單例,但是加鎖後會影響效率,所以往往不這樣使用。
雙重檢查鎖定
public class Slacker { //volatile关键字的作用 //1、保证内存可见性:保证每个线程访问volatile修饰的共享变量时获取到的都是最新的。 //2、防止指令重排序--通过内存屏障实现 private static volatile Slacker slacker = null; private Slacker() { } /** * 双重检查锁解决线程同步问题 * @return */ public static Slacker getInstanceDoubleLock() { if(slacker == null) { synchronized (Slacker.class) { if(slacker == null) { slacker = new Slacker(); } } } return slacker; } }
這種方式採用雙鎖定機制,能夠適應多執行緒並發存取的情況,且能保持高效能。
靜態內部類別實作
/** * 静态内部类方式实现单例模式 * * 当StaticInnerClass第一次被加载时,并不需要去加载StaticInnerClassHoler,只有当getInstance()方法第一次被调用时, * 才会去初始化staticInnerClass,第一次调用getInstance()方法会导致虚拟机加载StaticInnerClassHoler类,这种方法不仅能 * 确保线程安全,也能保证单例的唯一性,同时也延迟了单例的实例化。 * * @author chenf * */ public class StaticInnerClass { private StaticInnerClass() { } // 静态内部类 private static class StaticInnerClassHoler { // 在静态内部类中定义外部类的实例 private static StaticInnerClass staticInnerClass = new StaticInnerClass(); } /** * 获取时调用静态内部类的类属性获取外部类的实例 * * @return */ public static StaticInnerClass getInstance() { return StaticInnerClassHoler.staticInnerClass; } }
這種方式不僅可以實現多執行緒的安全訪問,同時還可以使用內部類別載入機制達到延遲載入的目的。
以上是淺談Java中幾種常用設計模式之單例模式的詳細內容。更多資訊請關注PHP中文網其他相關文章!