饿汉式(最简单的单例实现方式)
class Singleton { private static Singleton ourInstance = new Singleton(); private Singleton() { } public static Singleton newInstance() { return ourInstance; } } 12345678910 12345678910应用场景:
要求直接在应用启动时加载并初始化单例对象要求初始化速度非常快且占用内存非常小懒汉式
懒汉式与饿汉式最大的区别是单例的初始化操作的时机:
饿汉式:自动进行单例的初始化懒汉式:有需要的时候才手动调用newInstance()进行单例的初始化操作 class Singleton { private static Singleton ourInstance = null; private Singleton() { } public static Singleton newInstance() { if( ourInstance == null){ ourInstance = new Singleton(); } return ourInstance; } } 12345678910111213 12345678910111213应用场景:
单例初始化的操作耗时比较长而应用对于启动速度又有要求单例的占用内存比较大单例只是在某个特定场景的情况下才会被使用,即按需延迟加载单例。在多线程的情况下:
对于“饿汉式单例模式”:适用,因为JVM只会加载一次单例类;对于“懒汉式单例模式”:不适用,因为“懒汉式”在创建单例时是线程不安全的,多个线程可能会并发调用 newInstance 方法从而出现重复创建单例对象的问题。在同步锁的基础上( synchronized (Singleton.class) 外)添加了一层if,这是为了在Instance已经实例化后下次进入不必执行 synchronized (Singleton.class) 获取对象锁,从而提高性能。
class Singleton { private volatile static Singleton ourInstance = null; private Singleton() { } public static Singleton newInstance() { if( ourInstance == null){ synchronized (Singleton.class){ if( ourInstance == null){ ourInstance = new Singleton(); } } } return ourInstance; } } 1234567891011121314151617 1234567891011121314151617在JVM进行类加载的时候会保证数据是同步的,我们采用内部类实现:在内部类里面去创建对象实例。 只要应用中不使用内部类 JVM 就不会去加载这个单例类,也就不会创建单例对象,从而实现“懒汉式”的延迟加载和线程安全。
class Singleton { //在装载该内部类时才会去创建单例对象 private static class Singleton2{ private static Singleton ourInstance = new Singleton(); } private Singleton() { } public static Singleton newInstance() { return Singleton2.ourInstance; } } 12345678910111213 12345678910111213最简洁、易用的单例实现方式,(《Effective Java》推荐)
package org.mlinge.s10; public class ClassFactory{ private enum MyEnumSingleton{ singletonFactory; private MySingleton instance; private MyEnumSingleton(){//枚举类的构造方法在类加载是被实例化 instance = new MySingleton(); } public MySingleton getInstance(){ return instance; } } public static MySingleton getInstance(){ return MyEnumSingleton.singletonFactory.getInstance(); } } class MySingleton{//需要获实现单例的类,比如数据库连接Connection public MySingleton(){} }