单例模式
单例是java中常见的模式,大多数人对这个都有一定的了解。
单例模式具有以下特点
1.只有一个实例对象
2.这个对象由自身类创建
3.这个对象由自身类提供
单例写法有好多种,今天来说说饿汉模式和懒汉模式
一丶饿汉模式
//饿汉模式 class EagerSingleton { private EagerSingleton() {} private static EagerSingleton instance = new EagerSingleton(); public EagerSingleton getInstance(){ return instance; } }
饿汉模式的实例在类初始化的时候就创建完成所以天生就是线程安全
二丶懒汉模式
public class LazySingleton { private static LazySingleton instance = null; private LazySingleton(){}; //普通懒汉模式 public static LazySingleton getInstance(){ if(instance == null){ instance = new LazySingleton(); } return instance; } //线程安全 public static synchronized LazySingleton getInstance2(){ if(instance == null){ instance = new LazySingleton(); } return instance; } //双重验证 public static LazySingleton getInstance3(){ if(instance == null){ synchronized (LazySingleton.class){ if(instance == null){ instance = new LazySingleton(); } } } return instance; } }
饿汉模式和懒汉模式的区别
饿汉就是类一旦加载,就把单例初始化。
而懒汉只有当调用get方法的时候,才回去初始化这个单例。
饿汉模式天生就是线程安全,
懒汉模式是非线程安全的,所以才有了上面几种创建方式。
理论上懒汉在资源占用上会比饿汉少,但是饿汉加入线程安全性能也会下降不少。
下面再来看一个懒汉的创建方式
public class LazySingleton { private static LazySingleton instance = null; private LazySingleton(){}; //静态内部类 private static class LazySingletonInner{ private static LazySingleton singleton = new LazySingleton(); } public static LazySingleton getInstance(){ return LazySingletonInner.singleton; } }
用静态内部类的方法既实现了线程安全,又避免了同步带来的性能影响。
下面总结一些单例模式的优点
(1)由于单例模式在内存中只有一个实例,减少了内存开支,特别是一个对象需要频繁地创建、销毁时,单例模式的优势就非常明显。
(2)由于单例模式只生成一个实例,所以减少了系统的性能开销,当一个对象的产生需要比较多的资源时,可以通过在应用启动时直接产生一个单例对象,然后用永久驻留内存的方式来解决。
(3)单例模式可以避免对资源的多重占用,例如一个写文件操作,由于只有一个实例存在内存中,避免对同一个资源文件的同时写操作。
(4)单例模式可以在系统设置全局的访问点,优化和共享资源访问,例如,可以设计一个单例类,负责所有数据表的映射处理。