单例模式是常见的两种实现方式是懒汉模式(类加载时不初始化;在类加载时,不创建实例,因此类加载速度快,但运行时获取对象的速度慢)和饿汉模式(在类加载时就完成了初始化;所以类加载较慢,但获取对象的速度快)。
1、懒汉模式
这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized,线程不安全,在多线程不能正常工作。
优化:加锁
2、饿汉模式
描述:这种方式比较常用,但容易产生垃圾对象。
优点:没有加锁,执行效率会提高。
缺点:类加载时就初始化,浪费内存。
对于饿汉模式创建单例类,不能说该类是线程安全的。只能说该类实现了单例。在多线程情况下如果该类有其他属性(成员变量),有可能会造成多线程并发问题,这就不是一个线程安全的类了。所以你不能说他是线程安全的。线程安全的类必须保证在多线程环境下对其属性操作的时候不会出现可见性问题(读缓存导致,如cpu缓存,缓存的时差性导致的数据对其他线程不可见),原子性问题(线程切换,由于操作系统是时分复用的(cpu,内存,io等其他设备速率差距太过庞大导致现在主流操作系统是划时间片的,由于进程切换不共享内存地址空间等(切换耗费时间巨大(相对于机器)),但是线程切换共享,所以现在主流系统使用线程切换)),编译器优化问题(可能发生的指令重排问题)。这个时候才可以说这个类是线程安全的。类的线程安全和单例类是两个概念。
多线程情况下如何使用单例模式??
推荐使用两种方式:静态内部类和双重检验锁(DCL,即double-check locking)
1、静态内部类
2、双重检验锁(DCL,即double-check locking)