单例模式
核心作用:保证一个类只有一个实例,并且提供一个访问该实例的全局访问点。
常见应用场景:
- Windows 的任务管理器
- Windows的回收站
- 网站的计数器,一般也是采用单例模式实现
- 项目中 读取配置文件的类,一般也只有一个对象
- 数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源
- Spring 中,每个Bean默认就是单例的,这样的优点是Spring容器可管理
单例模式的优点:
- 由于单例模式只生成一个实例,减少了系统性能开销,当一个对象的产生需要比较多的
资源时,如读取配置,产生其他依赖对象时,则可以通过在应用启动时直接产生一个单例
对象,然后永久驻留内存的方式来解决。
- 单例模式可以在系统设置全局访问点,优化环共享资源访问,例如可以设计一个单例类,
负责所有数据表的映射处理。
常见的五种单例模式实现方式:
饿汉式:线程安全,调用效率高,但是不能延时加载
懒汉式:线程安全,调用效率不高,但是可延时加载
双重检测锁式:由于JVM 底层内部模型原因,偶尔出现问题。不建议使用
静态内部类式:线程安全,调用效率高,但是可以延时加载
枚举单例:线程安全,调用效率高,不能加载延时
饿汉式:
/**
* 饿汉式单例模式
* @author l
*
*/
public class SingletonTest01 {
private SingletonTest01(){
}
//类初始化时,立即加载这个对象
private static SingletonTest01 instance = new SingletonTest01();
public static SingletonTest01 getInstance(){
return instance;
}
}
懒汉式:
/**
* 懒加载 延时加载
* @author l
*
*/
public class SingletonTest02 {
//类初始化时 不初始化这个对象
private static SingletonTest02 instance ;
private SingletonTest02(){
}
//同步方法,调用效率降低
public static synchronized SingletonTest02 getinsntance(){
if(instance ==null){
instance =new SingletonTest02();
}
return instance;
}
}
双重检测锁式
偶尔会出问题 这里就不具体展示了
静态内部类式
兼备了并发高效调用和延时加载的优势
/**
* 静态内部类实现,也是一种懒加载
* @author l
*
*/
public class SingletonTest03 {
private SingletonTest03 (){
}
//静态内部类
private static class SingletonClassinstance{
private static final SingletonTest03 instance = new SingletonTest03();
}
public static SingletonTest03 getInstance(){
return SingletonClassinstance.instance;
}
}
枚举单例
无延时加载
/**
* 枚举实现单例模式
* @author l
*
*/
public enum SingletonTest04 {
//这个枚举元素,本事就是单例对象
INSTANCE;
//增加自己需要的操作
public void singletonOperation(){
}
}
那么我们应该如何选择?
单例对象 占用资源少,不需要延时加载
- 枚举式好于饿汉式
单例对象 占用资源大,需要延时加载
- 静态内部类 好于懒汉式
以上仅用于个人学习,如有错误请指出!