在Java语言中,单例模式有两大好处:
- 减少频繁的穿创建对象造成系统资源的浪费,尤其是对于一些重量级的对象的创建。
- 减少内存的浪费,会降低GC的压力,缩短GC停顿时间。
单例模式的核心在于通过一个接口返回一个唯一的对象实例。
实现方式一饿汉式:
/**
* @author 坏小孩
* 单例设计模式(饿汉式)
*/
public class Singleton {
//条件一:构造方法私有化
private Singleton(){
System.out.println("对象创建");
}
//条件二: 创建私有化对象实例
private static Singleton instance=new Singleton();
//条件三 :对外提供静态访问方法
public static Singleton getInstance() {
return instance;
}
}
关于饿汉式的优缺点:
优点:实现起来简单,没有多线程同步问题。
缺点:当类被加载是,会初始化static的instance,静态变量被创建并且分配内存空间,从这以后,这个static的instance对象便会一直占用这段内存(即使你没有用到这个实例),当类被卸载时,静态变量被摧毁,并且释放所占的内存,因此会在某些特定的条件下会耗费内存。
实现方式二:
/**
* @author 坏小孩
* 单例设计模式(懒汉式)
*/
public class Singleton {
//条件一:构造方法私有化
private Singleton(){
System.out.println("对象创建");
}
//条件二: 创建私有化成员变量
private static Singleton instance;
//条件三 :对外提供静态访问方法
public static Singleton getInstance() {
if(instance==null){
instance=new Singleton();
}
return instance;
}
}
懒汉模式的优缺点:
优点:实现起来简单,当类被加载时静态变量static的instance没有被分配内存空间,当getInstance方法第一次被调用时才会初始化instance变量,并且分配内存空间,因此在某些特定的情况下会节约内存空间。
缺点:在多线程的环境下,这种实现方式就是完全错误的,根本就不能保证单例的状态。
实现三:线程安全的懒汉式
/**
* @author 坏小孩
* 单例设计模式(线程安全懒汉式)
*/
public class Singleton {
//条件一:构造方法私有化
private Singleton(){
System.out.println("对象创建");
}
//条件二: 创建私有化成员变量
private static Singleton instance;
//条件三 :对外提供加锁的静态访问方法
public static synchronized Singleton getInstance() {
if(instance==null){
instance=new Singleton();
}
return instance;
}
}
优点:在多线程的情形下保证懒汉式的线程安全。
缺点:因为加锁所以效率很低,显然不是最佳方案。
实现方法四:DCL双检查锁机制(DCL:double checked locking)
/**
* @author 坏小孩
* 单例设计模式(线程安全懒汉式)
*/
public class Singleton {
//条件一:构造方法私有化
private Singleton(){
System.out.println("对象创建");
}
//条件二: 创建私有化成员变量
private static Singleton instance;
//条件三 :对外提供加锁的静态访问方法
public static Singleton getInstance() {
// 第一次检查instance是否被实例化出来,如果没有进入if块
if(instance==null){
// 某个线程取得了类锁,实例化对象前第二次检查instance是否已经被实例化出来,如果没有,才最终实例出对象
synchronized(Singleton.class){
if(instance==null){
instance=new Singleton();
}
}
}
return instance;
}
}
方法四算是单例模式的最佳实现方式。内存占用率低,效率高,线程安全,多线程操作原